Skip to main content
Explorer II
September 13, 2025
Solved

FDCAN tx & rx FIFO size

  • September 13, 2025
  • 1 reply
  • 507 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

    This topic has been closed for replies.
    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

    Graduate II
    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
    Explorer II
    September 13, 2025

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

    MHoll.2Answer
    Graduate II
    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