cancel
Showing results for 
Search instead for 
Did you mean: 

How to properly handle FDCAN TX FIFO

PKavv.1
Associate II

Hello,

I have a STM32G431KB on a custom PCB and got the CAN bus to work. The only problem I have is that the TX FIFO is always filling up and the bus stops after 127 errors.

The workaround I have is to abort the TX request.

/* Add message to Tx FIFO */
if (HAL_FDCAN_GetTxFifoFreeLevel(&hfdcan1) > 0)
{
  if (HAL_FDCAN_AddMessageToTxFifoQ(&hfdcan1, &FDCAN1_TxHeader, FDCAN1_TxData) != HAL_OK) {
    Error_Handler();
  }
}
else
{
  uint32_t txFifoRequest = HAL_FDCAN_GetLatestTxFifoQRequestBuffer(&hfdcan1);
  if (HAL_FDCAN_IsTxBufferMessagePending(&hfdcan1, txFifoRequest)) {
      HAL_FDCAN_AbortTxRequest(&hfdcan1, txFifoRequest);
  }
}

This however doesn't feel like a proper solution. How can I correctly implement the use of the TX FIFO without aborting messages?

7 REPLIES 7
TDK
Guru

If the TX FIFO is full, you need to wait for it to empty before adding more data. Can't send more data than the bus allows.

If you feel a post has answered your question, please click "Accept as Solution".
PKavv.1
Associate II

This PCB is connected to another embedded system, the Nvidia Jetson TX2. How can I make sure that the TX FIFO won't be completely filled before the Jetson has booted up to acknowledge CAN messages?

I would like to know how to solve this without altering the interval of the sent messages (currently at 10Hz). If I add a second buffer, I will introduce a delay that can not go away if the interval stays the same.

TDK
Guru

> How can I make sure that the TX FIFO won't be completely filled before the Jetson has booted up to acknowledge CAN messages? I would like to know how to solve this without altering the interval of the sent messages (currently at 10Hz).

If there are no guarantees on how long it takes to boot up, you can't. The buffer is not infinite.

If you know how long it takes to boot up, you can calculate whether or not it will work based on your rate and the buffer size.

If you feel a post has answered your question, please click "Accept as Solution".

If you know how long it takes to boot up, you can calculate whether or not it will work based on your rate and the buffer size.

I did check out the memory management (FDCAN_MsgRamAddressTypeDef ) of the CAN bus, but I can not figure out how to properly set it up, as it requires to use addresses with an offset.

Currently the TX FIFO can hold 3 messages without modifying anything. FDCAN_MsgRamAddressTypeDef has the parameter TxFIFOQSA, which specifies the Tx FIFO/Queue starting address. I am not sure if this is directly linked to the amount of messages that can be stored in the TX FIFO.

You can use the following function to check for errors:

FDCAN_ProtocolStatusTypeDef psr;
 
/* get actual psr value */
HAL_FDCAN_GetProtocolStatus(fdcanHandle, &psr);

Inside psr (Protocol Status Register) you can find the register LEC (Last Error Code). With the value you can check for every error on the physical bus:

/** @defgroup FDCAN_protocol_error_code FDCAN protocol error code
  * @{
  */
#define FDCAN_PROTOCOL_ERROR_NONE      ((uint32_t)0x00000000U) /*!< No error occurred        */
#define FDCAN_PROTOCOL_ERROR_STUFF     ((uint32_t)0x00000001U) /*!< Stuff error               */
#define FDCAN_PROTOCOL_ERROR_FORM      ((uint32_t)0x00000002U) /*!< Form error                */
#define FDCAN_PROTOCOL_ERROR_ACK       ((uint32_t)0x00000003U) /*!< Acknowledge error         */
#define FDCAN_PROTOCOL_ERROR_BIT1      ((uint32_t)0x00000004U) /*!< Bit 1 (recessive) error   */
#define FDCAN_PROTOCOL_ERROR_BIT0      ((uint32_t)0x00000005U) /*!< Bit 0 (dominant) error    */
#define FDCAN_PROTOCOL_ERROR_CRC       ((uint32_t)0x00000006U) /*!< CRC check sum error       */
#define FDCAN_PROTOCOL_ERROR_NO_CHANGE ((uint32_t)0x00000007U) /*!< No change since last read */

Hello @PKavv.1​ ,

have you been able to solve the issue and get mor information on how to set up the CAN-Controller properly?

I use a STM32G474, TX works, but I do not get any RX Callback and I also tumbled over the RAM confic and there should be s asetting for the queue if it is full(overwrite the old or ignore the new frame)

There is a presenatation, but I could not find any information on how to use the described functionalities: STM32G4-Peripheral-Flexible_Datarate_Controller_Area_Network_FDCAN.pdf I could also not figure out ho wrote it.

Best Regards, Seppel

Karl Yamashita
Lead III

@PKavv.1​ Why don't you have the Jetson send a SOH message when it is up and running? Then the STM32G431KB can start sending CAN messages.

Tips and Tricks with TimerCallback https://www.youtube.com/@eebykarl
If you find my solution useful, please click the Accept as Solution so others see the solution.