Skip to main content
Graduate
September 3, 2025
Solved

FDCAN with BRS activated: Problem transmitting 64 Bytes on FDCAN

  • September 3, 2025
  • 5 replies
  • 944 views

Hi all,

I am trying to use FDCAN with Baud rate switch (500 kB / 2 MBit) activated and I want to send 64 Byte.

Processor is STM32H7A3. Project was set up with CubeMX V. 6.11.1 and HAL FW_H7 V1.11.2. Clock for FDCAN is 80 MHz.

 

The problem is that the system only sends with 500 kB and 8 Bytes only.

I am transmitting the data to my PC using a PEAK USB dongle (FDCAN capable with BRS) and in parallel check the messages on a scope. 

I don't know, why it doesn't switch to 2 MBit and I only see  8 Bytes with 500 kBit on my scope and on PCAN-Explorer.

Here my init and transmit code sequences:

FDCAN_HandleTypeDef* phCan;

phCan = &hfdcan1;
phCan->Instance = FDCAN1;

phCan->Init.Mode = FDCAN_MODE_NORMAL; 
phCan->Init.FrameFormat = FDCAN_FRAME_FD_BRS;

phCan->Init.AutoRetransmission = ENABLE; 
phCan->Init.TransmitPause = DISABLE;

phCan->Init.NominalPrescaler = 10;
phCan->Init.NominalSyncJumpWidth = 1;
phCan->Init.NominalTimeSeg1 = 11;
phCan->Init.NominalTimeSeg2 = 4;

phCan->Init.DataPrescaler = 2;
phCan->Init.DataSyncJumpWidth = 1;
phCan->Init.DataTimeSeg1 = 14;
phCan->Init.DataTimeSeg2 = 5;

phCan->Init.MessageRAMOffset = 0;
phCan->Init.StdFiltersNbr = 0;
phCan->Init.ExtFiltersNbr = 0;

phCan->Init.RxFifo0ElmtsNbr = 16; // 0..64
phCan->Init.RxFifo1ElmtsNbr = 16;
phCan->Init.RxBuffersNbr = 10;

phCan->Init.RxFifo0ElmtSize = FDCAN_DATA_BYTES_64;
phCan->Init.RxFifo1ElmtSize = FDCAN_DATA_BYTES_64;
phCan->Init.RxBufferSize = FDCAN_DATA_BYTES_64;


phCan->Init.TxEventsNbr = 0;
phCan->Init.TxBuffersNbr = 0;

phCan->Init.TxFifoQueueElmtsNbr = 16;
phCan->Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION;

phCan->Init.TxElmtSize = FDCAN_DATA_BYTES_64;

phCan->msgRam.StandardFilterSA = 0;
phCan->msgRam.ExtendedFilterSA = 0;
phCan->msgRam.RxFIFO0SA = 0;
phCan->msgRam.RxFIFO1SA = 0;
phCan->msgRam.RxBufferSA = 0;
phCan->msgRam.TxEventFIFOSA = 0;
phCan->msgRam.TxBufferSA = 0;
phCan->msgRam.TxFIFOQSA = 0;
phCan->msgRam.TTMemorySA = 0;
phCan->msgRam.EndAddress = 0;
phCan->ErrorCode = 0;


halErr = HAL_FDCAN_Init(phCan);

halErr = HAL_FDCAN_Start(phCan);

----------------------------------

TxHeader.IdType = FDCAN_STANDARD_ID;
TxHeader.TxFrameType = FDCAN_DATA_FRAME;
TxHeader.ErrorStateIndicator = FDCAN_ESI_ACTIVE;

TxHeader.FDFormat = FDCAN_FRAME_FD_BRS;
TxHeader.BitRateSwitch = FDCAN_BRS_ON;

TxHeader.TxEventFifoControl = FDCAN_STORE_TX_EVENTS;//FDCAN_NO_TX_EVENTS;
TxHeader.MessageMarker = 0;

TxHeader.Identifier = 0x55;

TxHeader.DataLength = FDCAN_DLC_BYTES_64;

halErr = HAL_FDCAN_AddMessageToTxFifoQ(phfdcan, &TxHeader, TxData); // TxData = 64 Bytes

Is there anything missing or wrong?

Thank you for any support or hints.

BR GS

Post edited by the ST moderator to follow the community rule especially for the code sharing.

 

 

    This topic has been closed for replies.
    Best answer by mƎALLEm

    Hello,

    First, please use </> button to share your code. Please refer to this post: How to insert source code

    Second, what is your transceiver allowed bitrate bandwidth?

    3rd, what is your clock source? HSI or a crystal?

    4th, please call the following before the call of HAL_FDCAN_Start():

     /**
     * Configure and enable Tx Delay Compensation, required for BRS mode.
     * TdcOffset default recommended value: DataTimeSeg1 * DataPrescaler
     * TdcFilter default recommended value: 0
     */
     if (HAL_FDCAN_ConfigTxDelayCompensation(&hfdcan1, (hfdcan1.Init.DataPrescaler * hfdcan1.Init.DataTimeSeg1), 0U) != HAL_OK)
     {
     Error_Handler();
     }
    
     if (HAL_FDCAN_EnableTxDelayCompensation(&hfdcan1) != HAL_OK)
     {
     Error_Handler();
     }

     

    5 replies

    mƎALLEmAnswer
    Technical Moderator
    September 3, 2025

    Hello,

    First, please use </> button to share your code. Please refer to this post: How to insert source code

    Second, what is your transceiver allowed bitrate bandwidth?

    3rd, what is your clock source? HSI or a crystal?

    4th, please call the following before the call of HAL_FDCAN_Start():

     /**
     * Configure and enable Tx Delay Compensation, required for BRS mode.
     * TdcOffset default recommended value: DataTimeSeg1 * DataPrescaler
     * TdcFilter default recommended value: 0
     */
     if (HAL_FDCAN_ConfigTxDelayCompensation(&hfdcan1, (hfdcan1.Init.DataPrescaler * hfdcan1.Init.DataTimeSeg1), 0U) != HAL_OK)
     {
     Error_Handler();
     }
    
     if (HAL_FDCAN_EnableTxDelayCompensation(&hfdcan1) != HAL_OK)
     {
     Error_Handler();
     }

     

    GS1Author
    Graduate
    September 3, 2025

    Hello,

    thank you for your help:

    - The transceiver is TCAN1042HG and can do up to 5 MBit 

    - Clock source for the system is a Crystal 8 MHz, Clocksource for FDCAN is Clock Divider PLL2Q 

    - I inserted your code suggestion. However the result is the same as before. Only 8 Byte with 500 kBit arrive

    Any other ideas?

     

    BR GS

     

     

    Technical Moderator
    September 3, 2025

    Could you please attach your project? (tomorrow I'm out of office)

    Graduate II
    September 3, 2025

    Don't you need extended ID for BRS? 
    So try IdType = FDCAN_EXTENDED_ID

    Not sure though...

    GS1Author
    Graduate
    September 3, 2025

    Hi LCE,

    I tried that, but that doesn't solve the problem. It only changes the ID presentation.

     

    BR. GS

     

    GS1Author
    Graduate
    September 4, 2025

    Hello,

    I am sorry, but I can not send the complete project. We are using our own custom board and the FDCAN part is now a with BRS is a new required feature.

    Would the .IOC file be sufficient? Then you could include the posted initialisation and the send routine.

     

    Meanwhile I will do some more trials with the latest HAL library, debugging (with Keil ULINKPro), to confirm, that the registers are treated correctly, etc. 

     

    BR GS

    Graduate II
    September 4, 2025

    You are setting:

    TxHeader.FDFormat = FDCAN_FRAME_FD_BRS;

    This is not a valid value, so probably resets TX to BRS off.
    I guess you copied from init...

    Try setting it to:

    TxHeader.FDFormat = FDCAN_FD_CAN;

     

    GS1Author
    Graduate
    September 4, 2025

    Hello LCE,

    thank you for pointing this out. You are right! 

    I tried that and now this at least changes the behaviour, but not in the direction I expected: Now it doesn't send at all in FDCAN Mode. FIFO gets full and HAL_ERROR is returned when sending further messages. 

     

    I will keep on learning and trying...  

    BR GS

    Graduate II
    September 8, 2025

    I have often seen, that the sampling point is rather at 80%.

    This will depend on the accumulated delays due to the hardware bus structure, mainly due to capacitance.

    What are the TDC settings? Although TDC is probably not needed at 2 Mbps.

    Technical Moderator
    September 8, 2025

    The sampling point is around 80-87% in the arbitration phase. It seems not the case in the data phase. He needs to use Kvaser tool to confirm. I never had more than 60% in data phase with Kvaser tool.

    Graduate II
    September 8, 2025

    Can the Kvaser tool mimic a heavier bus load, so that other sampling points can be tested / make sense?