Skip to main content
Explorer
June 30, 2025
Question

STM32MP15: How to allocate FDCAN1 to the M4 and set bitrate 1Mbps & dbitrate 2Mbps?

  • June 30, 2025
  • 1 reply
  • 412 views

I am able to use FDCAN1 to communicate on the A7 by adding the following to `STM32MPU-Ecosystem-v6.0.0/Developer-Package/stm32mp1-openstlinux-6.6-yocto-scarthgap-mpu-v24.11.06/sources/arm-ostl-linux-gnueabi/linux-stm32mp-6.6.48-stm32mp-r1-r0/linux-6.6.48/arch/arm/boot/dts/st/stm32mp157f-dk2.dts`:

&m_can1 {
 pinctrl-names = "default", "sleep";
 pinctrl-0 = <&m_can1_pins_b>;
 pinctrl-1 = <&m_can1_sleep_pins_b>;
 clocks = <&scmi_clk CK_SCMI_HSE>, <&rcc FDCAN_K>;
 status = "okay";
};

  I'd like to allocate this can device to the M4 and use the example `STM32Cube_FW_MP1_V1.7.0/Projects/STM32MP157C-DK2/Examples/FDCAN`

I need help is fixing this code to get a bitrate of 1Mbps and dbitrate of 2Mbps.

 

static void MX_FDCAN1_Init(void)
{

 /* USER CODE BEGIN FDCAN1_Init 0 */

 /* USER CODE END FDCAN1_Init 0 */

 /* USER CODE BEGIN FDCAN1_Init 1 */

 /* USER CODE END FDCAN1_Init 1 */
 hfdcan1.Instance = FDCAN1;
 hfdcan1.Init.FrameFormat = FDCAN_FRAME_CLASSIC;
// hfdcan1.Init.FrameFormat = FDCAN_FRAME_FD_BRS;
 hfdcan1.Init.Mode = FDCAN_FRAME_FD_NO_BRS;
 hfdcan1.Init.AutoRetransmission = ENABLE;
 hfdcan1.Init.TransmitPause = ENABLE;
 hfdcan1.Init.ProtocolException = DISABLE;
	/* Bit time configuration:
	 ************************
	 Bit time parameter | Nominal | Data
	 ---------------------------|--------------|--------------
	 fdcan_ker_ck | 80 MHz | 80 MHz
	 Time_quantum (tq) | 12.5 ns | 12.5 ns
	 Prescaler | 2 | 1
	 Synchronization_segment | 1 tq | 1 tq
	 Propagation_segment | 19 tq | 5 tq
	 Phase_segment_1 | 10 tq | 2 tq
	 Phase_segment_2 | 10 tq | 2 tq
	 Synchronization_Jump_width | 10 tq | 2 tq
	 Bit_length | 80 tq = 1 �s | 10 tq = 0.125 �s
	 Bit_rate | 1 MBit/s | 8 MBit/s
	 */
 hfdcan1.Init.NominalPrescaler = 0x1;
 hfdcan1.Init.NominalSyncJumpWidth = 11;
 hfdcan1.Init.NominalTimeSeg1 = 68;
 hfdcan1.Init.NominalTimeSeg2 = 11;
// hfdcan1.Init.NominalPrescaler = 0;
// hfdcan1.Init.NominalSyncJumpWidth = 0xA;
// hfdcan1.Init.NominalTimeSeg1 = 0x1D;
// hfdcan1.Init.NominalTimeSeg2 = 0xA;
 hfdcan1.Init.DataPrescaler = 1;
 hfdcan1.Init.DataSyncJumpWidth = 4;
 hfdcan1.Init.DataTimeSeg1 = 31;
 hfdcan1.Init.DataTimeSeg2 = 8;
// hfdcan1.Init.DataPrescaler = 0x1;
// hfdcan1.Init.DataSyncJumpWidth = 0x2;
// hfdcan1.Init.DataTimeSeg1 = 0x7;
// hfdcan1.Init.DataTimeSeg2 = 0x2;
 hfdcan1.Init.MessageRAMOffset = 0;
// hfdcan1.Init.StdFiltersNbr = 0;
// hfdcan1.Init.ExtFiltersNbr = 0;
 hfdcan1.Init.StdFiltersNbr = 1;
 hfdcan1.Init.ExtFiltersNbr = 1;
 hfdcan1.Init.RxFifo0ElmtsNbr = 8;
 hfdcan1.Init.RxFifo0ElmtSize = FDCAN_DATA_BYTES_64;
 hfdcan1.Init.RxFifo1ElmtsNbr = 2;
 hfdcan1.Init.RxFifo1ElmtSize = FDCAN_DATA_BYTES_64;
 hfdcan1.Init.RxBuffersNbr = 8;
 hfdcan1.Init.RxBufferSize = FDCAN_DATA_BYTES_64;
 hfdcan1.Init.TxEventsNbr = 0;
 hfdcan1.Init.TxBuffersNbr = 0;
 hfdcan1.Init.TxFifoQueueElmtsNbr = 6;
 hfdcan1.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION;
 hfdcan1.Init.TxElmtSize = FDCAN_DATA_BYTES_64;

 HAL_StatusTypeDef hst = HAL_FDCAN_Init(&hfdcan1);
 if (hst != HAL_OK)
 {
 Error_Handler_Int(hst);
 }
 /* USER CODE BEGIN FDCAN1_Init 2 */
// SET_BIT(hfdcan1.Instance->TEST, FDCAN_TEST_LBCK);
// SET_BIT(hfdcan1->Instance->CCCR, FDCAN_CCCR_MON);
 /* USER CODE END FDCAN1_Init 2 */

}

Thanks! Steve.

    This topic has been closed for replies.

    1 reply

    Technical Moderator
    June 30, 2025

    Hello,

    I'm not a MPU expert, but these lines prevent you to use the peripheral in CAN-FD frame:

    hfdcan1.Init.FrameFormat = FDCAN_FRAME_CLASSIC;
    hfdcan1.Init.Mode = FDCAN_FRAME_FD_NO_BRS;

    Classic means CAN2.0. There is no data rate here and setting data timing are discarded by the peripheral.

    You need to activate the CAN-FD format with bitrate switching. For example with STM32H7 product the configuration is as the following:

     hfdcan.Init.FrameFormat = FDCAN_FRAME_FD_BRS;
     hfdcan.Init.Mode = FDCAN_MODE_NORMAL;

    and in the Tx header you need to tell that there will be a bitrate switching:

    TxHeader.BitRateSwitch = FDCAN_BRS_ON;

    This article may also help you: STM32 FDCAN running at 8 Mb/s on NUCLEO boards

     

    smangerAuthor
    Explorer
    June 30, 2025

    After I posted this, I realized that I had the frame format and mode wrong. I had since changed them. I'm more interested in the the variables for the `bitrate` and the `data bitrate`. I think that's what's causing me biggest headache.

    Technical Moderator
    June 30, 2025

    As I said I'm not expert of MPU products as I don't have idea about their environment but you need also to activate the delay compensation. See this thread. And use a Crystal as clock source for FDCAN.

    Also use Kvaser CAN-FD bit time calculator from this link.