Skip to main content
Associate III
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.

1 reply

mƎALLEm
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

 

"To give better visibility on the answered topics, please click on ""Accept as Solution"" on the reply which solved your issue or answered your question."
smangerAuthor
Associate III
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.

mƎALLEm
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.

"To give better visibility on the answered topics, please click on ""Accept as Solution"" on the reply which solved your issue or answered your question."