cancel
Showing results for 
Search instead for 
Did you mean: 

FDCAN tx & rx FIFO size

Kwame
Associate II

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

1 ACCEPTED SOLUTION

Accepted Solutions

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

 

View solution in original post

3 REPLIES 3
MHoll.2
Senior III

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);
}

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

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