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!

 

17 REPLIES 17

I tested using the HSE with an external crystal (Ref. below image), but the issue still persists.

 

 

WhatsApp Image 2025-09-19 at 15.50.34.jpeg

 

 

 


@Sumithra wrote:

I tested using the HSE with an external crystal (Ref. below image), but the issue still persists.


Even if the issue still persist, please keep that configuration.

To avoid unnecessary ping pongs, better to share your project so we can help you efficiently.

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.

Please find the attached project.

Ozone
Principal II

> Issue:
> The first few CAN frames transmit successfully.

No you don't.

Read the CAN specification, you cannot force a transmission on the CAN bus.
First, you can add a message to a queue (or Tx buffer), but the CAN peripheral only transmits it when the bus is free.
And second, the CAN peripheral will retry until the transmission is successful (or it turns itself off).

I am 100% sure your transmission attempts fail, because the bus is not set up correctly.
Check with a scope, and check the transmit and receive error counters (TEC, REC) in the CAN peripheral after each transmission attempt.
After a defined number of errors, the device goes first into passive mode, and then into "bus-off" mode.

I see your point. In my case, transmissions sometimes succeed, but not always. Could you help me pinpoint what part of the setup I should correct first?

What is your second device on the bus ?
CAN does not work with only one node. A successful transmission requires the acknowledge from another participant.
This could be a CAN dongle for a PC, if you configure it correctly (proper baudrate, and not in listen-only mode).

Check the physical signal, you could use a scope for that.
But if you need to deal with CAN more than once, get a PC CAN dongle (with appropriate software). I suppose the cheapest variant is a Raspberry Pi with a CAN shield and open source tools : https://github.com/ajouatom/canbus-tools

And you can monitor the success (or failure) of a transmission attempt in the debugger.
The TEC and REC counters are visible in the CAN register interface. If they go up after each transmission attempt, something is wrong.

If you have another STM32 board as second CAN device, you could connect the CAN signals (CAN_Tx, CAN_Rx and GND) directly, bypassing the transceivers. Rx/Tx would have to be crossed, then.
The usualy precautions for such direct connections between different boards apply ...

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.

What are you use to receive the data? The can bus analyzer? if in this case you can check the voltage of it, because i find that it will not receive data in many case when the voltage is lower than 5V.