2025-06-30 7:50 AM - last edited on 2025-06-30 7:55 AM by Andrew Neil
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.
2025-06-30 8:50 AM - edited 2025-06-30 8:55 AM
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
2025-06-30 8:56 AM
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.
2025-06-30 8:59 AM - edited 2025-06-30 9:02 AM
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.
2025-06-30 12:15 PM
I have added the delay compensation as shown in the thread from above. This did not change anything as far as I can tell.
I have updated the `stm32mp157f-dk2.dts` file so that instead of `m_can1`, it's now `m4_can1`.
&m4_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 rebuilt and uploaded the kernel, still no luck.
I'm not quite sure what this line means in the `dts` file (can I or do I need to assign one or more of these clocks to the M4?):
clocks = <&scmi_clk CK_SCMI_HSE>, <&rcc FDCAN_K>;
I'm not sure what the speeds of these clocks are on the `STM32MP157F-DK2`. That will have a big impact on the nominal bitrate and data bitrate calculations.