2025-09-12 9:53 PM
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?
Here is my configuration parameters.
Solved! Go to Solution.
2025-09-14 12:27 AM
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!
2025-09-13 7:24 AM
You can set the Different Buffer numbers and FIFO elements in CubeMX:
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);
}
2025-09-13 7:48 AM
Thanks for your response. I can’t find the RAM parameters in CubeMX. Are these parameters for the STM32H7R7?
2025-09-14 12:27 AM
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!