Skip to main content
Associate II
September 13, 2025
Solved

FDCAN tx & rx FIFO size

  • September 13, 2025
  • 1 reply
  • 509 views

Is there a way to set the FDCAN TX and RX FIFO sizes for STM32H7R7 in CubeIDE?

I snooped around and found a list of macros that are responsible for determining the FDCAN RAM size in the stm32h7rsxx_hal_fdcan.c. Do I just modify these values to set the FIFO sizes?

Screenshot 2025-09-13 at 12.44.55 AM.png

Here is my configuration parameters. 

Screenshot 2025-09-13 at 12.36.12 AM.png

Best answer by MHoll.2

Sorry, I didn't check your STM32H7 chip, the STM32H7R7 has the reduced FDCAN controller (with only 2K Byte of Message RAM, against the 10 KByte on other STM32H7 chips) this controller has a fixed FIFO configuration that can not be modified!

MHoll2_0-1757834607519.png

 

1 reply

MHoll.2
Senior III
September 13, 2025

You can set the Different Buffer numbers and FIFO elements in CubeMX:

MHoll2_0-1757773119235.png

Or You can make You one CANInit function (like I normaly do):

 

int32_t Can_init(eCanBus eChannel, uint16_t wArbitrationBaudrate, uint16_t wDataBaudrate, bool bFDCAN)
{
 FDCAN_HandleTypeDef *hfdcan;
 UINT ret;

 // TODO check if eChannel is valid
 // TODO check if wArbitrationBaudrate is valid
 // TODO check if wDataBaudrate is valid
 ret = tx_mutex_create(&MutexTXFDCan[eChannel], "TX", TX_INHERIT); // xSemaphoreCreateMutex();
 if (ret != TX_SUCCESS)
 {
 return (CAN_INIT_ERROR);
 }
 ret = tx_mutex_create(&MutexRXFDCan[eChannel], "RX", TX_INHERIT); //xSemaphoreCreateMutex();
 if (ret != TX_SUCCESS)
 {
 return (CAN_INIT_ERROR);
 }
 switch (eChannel)
 {
 case CAN_BUS_0:
 hfdcan = &hfdcan1;
 hfdcan1.Instance = FDCAN1;
 hfdcan->Init.MessageRAMOffset = 0;
 break;
 case CAN_BUS_1:
 hfdcan = &hfdcan2;
 hfdcan2.Instance = FDCAN2;
 hfdcan->Init.MessageRAMOffset = 0x350;
 break;
 case CAN_BUS_2:
 hfdcan = &hfdcan3;
 hfdcan3.Instance = FDCAN3;
 hfdcan->Init.MessageRAMOffset = 0x6A0;
 break;
 default:
 return (CAN_INIT_ERROR);
 break;
 }
 // Init Can driver selected
 HAL_FDCAN_Stop(hfdcan);
 HAL_FDCAN_DeInit(hfdcan);

 hfdcan->Init.Mode = FDCAN_MODE_NORMAL;
 hfdcan->Init.AutoRetransmission = ENABLE;
 hfdcan->Init.TransmitPause = DISABLE;
 hfdcan->Init.ProtocolException = DISABLE;

 // max DWORD per Instance is 853 DWORD (max. for all 3 Instance together is
 // 2560 DWORD)
 if (!bFDCAN)
 {
 hfdcan->Init.FrameFormat = FDCAN_FRAME_CLASSIC;
 // 64 * 3 = 192 DWORD
 hfdcan->Init.RxFifo0ElmtsNbr = 64; /* 64 x 8 Byte RX FIFO0 size */
 hfdcan->Init.RxFifo0ElmtSize = FDCAN_DATA_BYTES_8;
 hfdcan->Init.RxFifo1ElmtsNbr = 0; /* Do not used RX FIFO1 */
 hfdcan->Init.RxBuffersNbr = 0; /* Do not use RX buffers */
 hfdcan->Init.TxEventsNbr = 0; /* Do not use Events */
 hfdcan->Init.TxBuffersNbr = 0; /* Do not use TX buffers */
 // 32 * 3 = 96 DWORD
 hfdcan->Init.TxFifoQueueElmtsNbr = 32; /* 32 x 8 Byte TX FIFO size */
 hfdcan->Init.TxElmtSize = FDCAN_DATA_BYTES_8;
 hfdcan->Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION;
 }
 else
 {
 hfdcan->Init.FrameFormat = FDCAN_FRAME_FD_BRS;
 // 15 * 18 = 270 DWORD (max. for all 3 Instance together is 2560 DWORD)
 hfdcan->Init.RxFifo0ElmtsNbr = 15; /* 15 x 64 Byte RX FIFO0 size */
 hfdcan->Init.RxFifo0ElmtSize = FDCAN_DATA_BYTES_64;
 hfdcan->Init.RxFifo1ElmtsNbr = 0; /* Do not used RX FIFO1 */
 hfdcan->Init.RxBuffersNbr = 0; /* Do not use RX buffers */
 hfdcan->Init.TxEventsNbr = 0; /* Do not use Events */
 hfdcan->Init.TxBuffersNbr = 0; /* Do not use TX buffers */
 // 32 * 18 = 576 DWORD
 hfdcan->Init.TxFifoQueueElmtsNbr = 32; /* 32 x 64 Byte TX FIFO size */
 hfdcan->Init.TxElmtSize = FDCAN_DATA_BYTES_64; /* Max number of bytes per message in TX FIFO */
 hfdcan->Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION;
 }
 CanSetBaudrateData(hfdcan, wArbitrationBaudrate, wDataBaudrate);
 if (HAL_FDCAN_Init(hfdcan) != HAL_OK)
 {
 /* What should we return here? */
 return (CAN_INIT_ERROR);
 }
 /**
 * Configure and enable Tx Delay Compensation, required for BRS mode.
 * TdcOffset default recommended value: DataTimeSeg1 * DataPrescaler (set
 * trigger point to DataTimeSeg1 ??) TdcFilter default recommended value: 0 ?
 * --> To prevent early trigger a value >0 would be better --> needs testing
 * on HW
 */

 if (HAL_FDCAN_ConfigTxDelayCompensation(hfdcan, 8U, 0U) != HAL_OK)
 {
 return (CAN_INIT_ERROR);
 }
 if (HAL_FDCAN_EnableTxDelayCompensation(hfdcan) != HAL_OK)
 {
 return (CAN_INIT_ERROR);
 }

 // set RXFifo0 mode to Overwrite
 HAL_FDCAN_ConfigRxFifoOverwrite(hfdcan, FDCAN_RX_FIFO0, FDCAN_RX_FIFO_OVERWRITE);
 /*
 * Configure global filter that is used as last check if message did not pass
 * any of other filters:
 *
 * We do not rely on hardware filters in this example
 * and are performing software filters instead
 *
 * Accept non-matching standard ID messages
 * Accept non-matching extended ID messages
 */
 if (HAL_FDCAN_ConfigGlobalFilter(hfdcan, FDCAN_ACCEPT_IN_RX_FIFO0, FDCAN_ACCEPT_IN_RX_FIFO0, FDCAN_FILTER_REMOTE, FDCAN_FILTER_REMOTE) != HAL_OK)
 {
 return (CAN_INIT_ERROR);
 }

 /* Enable notifications */
 if (HAL_FDCAN_ActivateNotification(hfdcan, 0 | FDCAN_IT_RX_FIFO0_NEW_MESSAGE | FDCAN_IT_RX_FIFO1_NEW_MESSAGE | FDCAN_IT_TX_COMPLETE | FDCAN_IT_TX_FIFO_EMPTY | FDCAN_IT_BUS_OFF | FDCAN_IT_ARB_PROTOCOL_ERROR | FDCAN_IT_DATA_PROTOCOL_ERROR | FDCAN_IT_ERROR_PASSIVE | FDCAN_IT_ERROR_WARNING, 0xFFFFFFFF) != HAL_OK)
 {
 return (CAN_INIT_ERROR);
 }

 // enable IRQ
 switch (eChannel)
 {
 case CAN_BUS_0:
 NVIC_SetPriority(FDCAN1_IT0_IRQn, FDCAN1_IRQ_LEVEL);
 NVIC_SetPriority(FDCAN1_IT1_IRQn, FDCAN1_IRQ_LEVEL);
 NVIC_EnableIRQ(FDCAN1_IT0_IRQn);
 NVIC_EnableIRQ(FDCAN1_IT1_IRQn);
 break;
 case CAN_BUS_1:
 NVIC_SetPriority(FDCAN2_IT0_IRQn, FDCAN2_IRQ_LEVEL);
 NVIC_SetPriority(FDCAN2_IT1_IRQn, FDCAN2_IRQ_LEVEL);
 NVIC_EnableIRQ(FDCAN2_IT0_IRQn);
 NVIC_EnableIRQ(FDCAN2_IT1_IRQn);
 break;
 case CAN_BUS_2:
 NVIC_SetPriority(FDCAN3_IT0_IRQn, FDCAN2_IRQ_LEVEL);
 NVIC_SetPriority(FDCAN3_IT1_IRQn, FDCAN2_IRQ_LEVEL);
 NVIC_EnableIRQ(FDCAN3_IT0_IRQn);
 NVIC_EnableIRQ(FDCAN3_IT1_IRQn);
 break;
 default:
 return (CAN_INIT_ERROR);
 break;
 }
 if (HAL_FDCAN_Start(hfdcan) != HAL_OK)
 {
 return (CAN_INIT_ERROR);
 }

 return (CAN_OK);
}
KwameAuthor
Associate II
September 13, 2025

Thanks for your response. I can’t find the RAM parameters in CubeMX. Are these parameters for the STM32H7R7?

MHoll.2
MHoll.2Best answer
Senior III
September 14, 2025

Sorry, I didn't check your STM32H7 chip, the STM32H7R7 has the reduced FDCAN controller (with only 2K Byte of Message RAM, against the 10 KByte on other STM32H7 chips) this controller has a fixed FIFO configuration that can not be modified!

MHoll2_0-1757834607519.png