Showing results for 
Search instead for 
Did you mean: 

STM32 FDCAN Send CAN messages without ACK

Alberto MAHLE.
Associate II

Good morning:

I'm working with the STM32G431KB on my own board. In the project we send messages thanks to the FDCAN HAL module driver layer for wakeup other ECU by expecific CAN messages. 


I am working using Polling mode for FDCAN:

  hfdcan1.Instance = FDCAN1;
  hfdcan1.Init.ClockDivider = FDCAN_CLOCK_DIV1;
  hfdcan1.Init.FrameFormat = FDCAN_FRAME_CLASSIC;
  hfdcan1.Init.Mode = FDCAN_MODE_NORMAL;
  hfdcan1.Init.AutoRetransmission = DISABLE;
  hfdcan1.Init.TransmitPause = DISABLE; // 
  hfdcan1.Init.ProtocolException = DISABLE;
  hfdcan1.Init.NominalPrescaler = 9;
  hfdcan1.Init.NominalSyncJumpWidth = 1;
  hfdcan1.Init.NominalTimeSeg1 = 13;
  hfdcan1.Init.NominalTimeSeg2 = 2;
  hfdcan1.Init.DataPrescaler = 9;
  hfdcan1.Init.DataSyncJumpWidth = 1;
  hfdcan1.Init.DataTimeSeg1 = 13;
  hfdcan1.Init.DataTimeSeg2 = 2;
  hfdcan1.Init.StdFiltersNbr = 0;
  hfdcan1.Init.ExtFiltersNbr = 0;
  hfdcan1.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION;


I sent messages without problems thanks to the function: 

   TxHeader.DataLength = FDCAN_DLC_BYTES_8;
   TxHeader.IdType = FDCAN_STANDARD_ID;
   TxHeader.TxFrameType = FDCAN_DATA_FRAME;
   TxHeader.ErrorStateIndicator = FDCAN_ESI_PASSIVE;
   TxHeader.BitRateSwitch = FDCAN_BRS_OFF;
   TxHeader.FDFormat = FDCAN_CLASSIC_CAN;
   TxHeader.TxEventFifoControl = FDCAN_STORE_TX_EVENTS;
   TxHeader.MessageMarker = 0;
HAL_FDCAN_AddMessageToTxFifoQ(&hfdcan1, &TxHeader, data);



If there is any device connected, the system works correctly, because we receive ACK. 

The problem is that I need to be able to send messages without any device being active to send the ACK. in this case i received error FDCAN_PROTOCOL_ERROR_ACK and finally sends FDCAN_PROTOCOL_ERROR_NO_CHANGE.

The system fails and even if I reset the FDCAN, there is no way to be able to send CAN messages again.

How can I configure/send CAN messages without the need for ACK from another device?

What are my options ?



Isn't it useless to send a CAN message if there aren't any nodes active to receive the message? As for the error of not getting an ACK from other devices, that is all done in the CAN controller itself and not in FW.  

Alberto MAHLE.
Associate II

In our project, we can NOT ensure that there is always another active device listening on CAN Bus.

My question,

  • is it possible configuring the CAN module to avoid the ACK check?
  • It could be thanks to the FDCAN 0 and 1 interruptions.
  • Another option that I have seen is thanks to the external loop mode?
  • Any other option?

Thank you so much.

The CAN controller has to follow an ISO standard. It's all done in the hardware mechanism so nothing in FW can change that. Because you're trying to transmit without a bus connected, the TEC counter > 256 will put the CAN controller into BUS-OFF state.

Read more about the FDCAN_ESR register especially the TEC and REC bits and the notes on how the CAN controller can go back to normal state.



Thank you very much for the information.

I'm doing research, and in the document "rm0440-stm32g4-series-advanced-armbased-32bit-mcus-stmicroelectronics.pdf", I have not found anything except the "Restricted operation mode". You mean this?

How can I get the bus out of mode, BUS-OFF state?

It is true that this situation will occur to me rarely, but I prefer to avoid that the ECU seems blocked by this.


Sorry to sound like a bit of a newbie.

Thank you so much.

> The CAN controller has to follow an ISO standard. It's all done in the hardware mechanism so nothing in FW can change that. Because you're trying to transmit without a bus connected, the TEC counter > 256 will put the CAN controller into BUS-OFF state.

You don't get into BUS-Off state from one failed message, not even Error-passive.
Working with CAN as well, such a behavior would be unacceptable for our devices as well.
It seems a reset/reboot is required to get CAN working again.

My company's devices (ECUs) have to deal with such situations as well. A bus <can> be unpopulated. The ECU having 3 or more separate CAN busses, this state (one bus without device) is actually normal for some applications.

Senior III

I agree that sending only one message should not put the CAN peripheral in a blocked state.
At first I thought that the automatic retransmission was enabled (as it is by default) and that caused the peripheral to panic. If this happens, the bus off flag should become set and then it is explained in the RM how to re-enable the peripheral (not reset, rather re-init) to exit bus off state.
It is explained in the RM0444 (G0) under the FDCAN error counter register (footnote) on how to exit the bus off state.

I would also check that the HAL is really disabling the automatic retransmission bit in FDCAN CCCR. I can't believe that the No ACK exception is not handled correctly by the hardware.

Best regards.

Yes, I would definitely check the error counter register in this case.
The error registers and their behavior are part of the CAN spec that all devices usually follow.

Next option would be a PC CAN adapter (with respective PC software). Even the cheaper one's usually have a "listen only" setting which allows you some more insight without interfering.

Although I cannot comment on HAL usage/issues in this regard.
None of our ECUs is based on STM32 devices, and personally I don't use Cube/HAL for other reasons.