cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H745I-DISCO – CAN TXFIFO Buffer Full Issue

Sumithra
Associate II

Post edited by ST moderator to be inline with the community rules especially with the code sharing. In next time please use </> button to paste your code. Please read this post: How to insert source code.

Hi everyone,

I am working on Classic CAN communication using the STM32H745I-Discovery board with FDCAN2.
My target CAN configuration is 500 Kbps nominal baud rate with a 16 MHz clock.

Below is my initialization code:

static void MX_FDCAN2_Init(void)
{
hfdcan2.Instance = FDCAN2;
hfdcan2.Init.FrameFormat = FDCAN_FRAME_CLASSIC;
hfdcan2.Init.Mode = FDCAN_MODE_NORMAL;
hfdcan2.Init.AutoRetransmission = ENABLE;
hfdcan2.Init.TransmitPause = DISABLE;
hfdcan2.Init.ProtocolException = ENABLE;

// Timing config: 500 Kbps @ 16 MHz
hfdcan2.Init.NominalPrescaler = 1;
hfdcan2.Init.NominalSyncJumpWidth = 1;
hfdcan2.Init.NominalTimeSeg1 = 23;
hfdcan2.Init.NominalTimeSeg2 = 8;

hfdcan2.Init.DataPrescaler = 1;
hfdcan2.Init.DataSyncJumpWidth = 1;
hfdcan2.Init.DataTimeSeg1 = 1;
hfdcan2.Init.DataTimeSeg2 = 1;

hfdcan2.Init.MessageRAMOffset = 0;
hfdcan2.Init.StdFiltersNbr = 1;
hfdcan2.Init.ExtFiltersNbr = 0;
hfdcan2.Init.RxFifo0ElmtsNbr = 1;
hfdcan2.Init.RxFifo0ElmtSize = FDCAN_DATA_BYTES_8;
hfdcan2.Init.TxFifoQueueElmtsNbr = 1;
hfdcan2.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION;
hfdcan2.Init.TxElmtSize = FDCAN_DATA_BYTES_8;

if (HAL_FDCAN_Init(&hfdcan2) != HAL_OK) Error_Handler();

// Configure filter (accept all standard IDs)
FDCAN_FilterTypeDef filter;
filter.IdType = FDCAN_STANDARD_ID;
filter.FilterIndex = 0;
filter.FilterType = FDCAN_FILTER_MASK;
filter.FilterConfig = FDCAN_FILTER_TO_RXFIFO0;
filter.FilterID1 = 0x000;
filter.FilterID2 = 0x7FF;
HAL_FDCAN_ConfigFilter(&hfdcan2, &filter);

HAL_FDCAN_Start(&hfdcan2);

// Tx header
txHeader.Identifier = 0x123;
txHeader.IdType = FDCAN_STANDARD_ID;
txHeader.TxFrameType = FDCAN_DATA_FRAME;
txHeader.DataLength = FDCAN_DLC_BYTES_8;
txHeader.BitRateSwitch = FDCAN_BRS_OFF;
txHeader.FDFormat = FDCAN_CLASSIC_CAN;
txHeader.TxEventFifoControl = FDCAN_NO_TX_EVENTS;
txHeader.MessageMarker = 0;
}
And the send function:
HAL_StatusTypeDef CAN_Send(uint8_t* data)
{
if (HAL_FDCAN_AddMessageToTxFifoQ(&hfdcan2, &txHeader, data) == HAL_OK)
{   

           return HAL_OK;
}
else
{
         return HAL_ERROR;
}
}

Issue:

The first few CAN frames transmit successfully.

After that, the TXFIFO becomes full and no further frames are sent.

Sometimes it transmits several messages before stopping, sometimes only one or two.

 

What I tried so far:

  1. Increased TxFifoQueueElmtsNbr (tried more than 1).

  2. Verified hardware connections and ensured 120Ω termination resistor is present.

  3. Tested the receiver side (looped with another working board), and confirmed reception is fine there.

  4. Tried with both AutoRetransmission enabled/disabled.

  5. Verified the 500 Kbps baud rate configuration with 16 MHz clock.

Still, the issue persists.

Any guidance or working examples would be very helpful.

Thanks!

 

1 ACCEPTED SOLUTION

Accepted Solutions

Hello,

I tested your project with a little modification and there is no issue. I just connected another CAN node which is a NUCLEO-F767 board (CAN2.0) + a transceiver, and the latter is receiving the CAN frames from STM32H745I-DISCO without issues.

These are the frames send each 100ms:

mALLEm_0-1758641742972.png

This screenshot spots one frame:

mALLEm_1-1758641807647.png

A screenshot for IAR of the receiving CAN frame (F767 side) showing the Rx content changing in live (only data 0 and data 7 are changing):

mALLEm_2-1758641895245.png

Attached the projects that I used for the test.

Now, I'm pretty sure it's not a software issue and you have a hardware issue. Either with the transceiver or the wiring or something else. Maybe you swapped CAN_H and CAN_L? need to check.

Hope that helps.

 

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.

View solution in original post

17 REPLIES 17
Karl Yamashita
Principal

Are you queuing your CAN messages? Because if you send a bunch of messages and the Tx buffer is full, then you lose those messages. By using a queue, you can send those messages once the Tx buffer is available.

 

Also, use the </> to post code so that it's formatted and readable.

If a reply has proven helpful, click on Accept as Solution so that it'll show at top of the post.
CAN Jammer an open source CAN bus hacking tool
Sumithra
Associate II

Hi,
Thanks for your reply.

Right now I’m only using HAL_FDCAN_AddMessageToTxFifoQ() directly, so when the hardware Tx FIFO gets full I lose messages. I understand now that I should add a software queue on top and retry sending when space becomes available.

However, in my case I’m transmitting only one CAN frame every 1 second. Since a CAN frame takes just a few hundred microseconds on the bus, the Tx FIFO should normally be free by the time the next frame is sent, correct?

Karl Yamashita
Principal

What I tried so far:

Tested the receiver side (looped with another working board), and confirmed reception is fine there.


It's unclear what is happening. So, is this other working board continuously working and your main board is transmitting without getting full? What is the other node that you're trying to transmit to that is causing your main board to get full?

 

 

If a reply has proven helpful, click on Accept as Solution so that it'll show at top of the post.
CAN Jammer an open source CAN bus hacking tool

I’m using an Arduino Nano on the receiver side. I’ve tested the Nano as the receiver with different STM32 MCU board, and it is receiving the data without any errors

After start fdcan, the interrupt should be start
企业微信截图_17580915249987.png

What is the clock source of your FDCAN? Did you set HSE as main clock source for FDCAN?

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.

I was using HSI as the main clock source for FDCAN. I also tried switching to HSE as the main clock source, but the issue still persists.

I haven’t enabled any interrupts there. Do I still need to mention it?

In Normal mode you should use HSE with an external crystal as soon you are connected to another CAN node.

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.