cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H7 FDCAN 8 Mbit/s setup / docum. unclear SYNC_SEG

LCE
Principal

Heyho,

I don't get the FDCAN on a STM32H735g-DK working with 8 Mbit/s.

I feed the FDCANs with 80 MHz so that the "time quantum" is 12.5 ns to make 8 Mbit possible with the integers.

I use the recommended kvaser website for calculations:

https://www.kvaser.com/support/calculators/can-fd-bit-timing-calculator/#/canfd

/* clock / timing */
 
/* nominal = arbitration phase
 *	NBTP
 * 	80 MHz: tq = NominalPrescaler x (1/fdcan_ker_ck)
 *		->  tq = 12.5 ns
 *	data rate = 1 / ((SyncSeg + Seg1 + Seg2) * tq)
 *		with SyncSeg = 1
 *	0.5 Mbps = 160 * tq
 *		-> TimeSeg1 + TimeSeg2 = 159
 */
	phCan->Init.NominalPrescaler = 1;		/* tq = NominalPrescaler x (1/fdcan_ker_ck) */
#if( 1 )
/* 5000 ppm */
	phCan->Init.NominalTimeSeg1 = 138;		/* NTSEG1 1..256, NominalTimeSeg1 = Propagation_segment + Phase_segment_1 */
	phCan->Init.NominalTimeSeg2 = 21;		/* NTSEG2 1..128 */
	phCan->Init.NominalSyncJumpWidth = 20;		/* NSJW   1..128 should be < NTSEG2 */
#else
/* 500 ppm */
	phCan->Init.NominalTimeSeg1 = 153;		/* NTSEG1 1..256, NominalTimeSeg1 = Propagation_segment + Phase_segment_1 */
	phCan->Init.NominalTimeSeg2 = 6; 		/* NTSEG2 1..128 */
	phCan->Init.NominalSyncJumpWidth = 3; 		/* NSJW   1..128 should be < NTSEG2 */
#endif
 
/* data = data phase with bit rate switching
 *	DBTP
 * 	80 MHz: tq = DataPrescaler x (1/fdcan_ker_ck)
 *		->  tq = 12.5 ns
 *	data rate = 1 / ((SyncSeg + Seg1 + Seg2) * tq)
 *		with SyncSeg = 1
 */
	phCan->Init.DataPrescaler = 1;		/* DBRP 1..32 */
#if CAN_FD_DATA_8MB
/* 8 Mbps = 10 * tq
 *	-> TimeSeg1 + TimeSeg2 = 9
 */
	phCan->Init.DataTimeSeg1 	= 5;		/* NTSEG1 1..32, NominalTimeSeg1 = Propagation_segment + Phase_segment_1 */
	phCan->Init.DataTimeSeg2 	= 4;        /* NTSEG2 1..16 */
	phCan->Init.DataSyncJumpWidth 	= 4;        /* NSJW   1..16 should be < NTSEG2 */
#else
/* 2 Mbps = 40 * tq
 *	-> TimeSeg1 + TimeSeg2 = 39
 */
	phCan->Init.DataTimeSeg1 	= 24;		/* NTSEG1 1..32, NominalTimeSeg1 = Propagation_segment + Phase_segment_1 */
	phCan->Init.DataTimeSeg2 	= 15;       /* NTSEG2 1..16 */
	phCan->Init.DataSyncJumpWidth 	= 14;       /* NSJW   1..16 should be < NTSEG2 */
#endif

0.5 Mbit in arbitration phase is working (checked bit rate on scope), so is data rate of 2 Mbit/s (checked bit rate on scope).

When using the 8 Mbit settings, the peripheral "hangs" after the first output, which doen's show any sign of BSR / 8 Mbit.

Any ideas?

Or even better any examples how to get to 8 Mbit/s ?

26 REPLIES 26
LCE
Principal

@Imen DAHMEN​  Any news?

I tried everything, the only way I get 8 Mbit to work is putting FDCAN in external loopback mode.

Really strange.

Until 4 Mbit everything fine.

Here my current init, same for FDCAN2.

/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
/* FDCAN1 init function */
void MX_FDCAN1_Init(uint32_t u32DataRate)
{
	FDCAN_HandleTypeDef *phCan = &hCan1;
	FDCAN_FilterTypeDef sFilterConfig = { 0 };
 
	phCan->Instance = FDCAN1;
 
	phCan->Init.FrameFormat 			= FDCAN_FRAME_FD_BRS;
	phCan->Init.Mode 					= FDCAN_MODE_NORMAL;//FDCAN_MODE_EXTERNAL_LOOPBACK;//
	phCan->Init.AutoRetransmission 		= DISABLE;
	phCan->Init.TransmitPause 			= ENABLE;
	phCan->Init.ProtocolException 		= ENABLE;
 
/* clock / timing */
 
/* nominal = arbitration phase
 *	NBTP
 * 	80 MHz: tq = NominalPrescaler x (1/fdcan_ker_ck)
 *		->  tq = 12.5 ns
 *	data rate = 1 / ((SyncSeg + Seg1 + Seg2) * tq)
 *		with SyncSeg = 1
 *	0.5 Mbps = 160 * tq
 *		-> TimeSeg1 + TimeSeg2 = 157
 */
	phCan->Init.NominalPrescaler 		= 1;		/* tq = NominalPrescaler x (1/fdcan_ker_ck) */
#if( 1 )
/* 5000 ppm */
	phCan->Init.NominalTimeSeg1 		= 138;		/* NTSEG1 1..256, NominalTimeSeg1 = Propagation_segment + Phase_segment_1 */
	phCan->Init.NominalTimeSeg2 		= 21;		/* NTSEG2 1..128 */
	phCan->Init.NominalSyncJumpWidth 	= 20;		/* NSJW   1..128 should be < NTSEG2 */
#else
/* 500 ppm */
	phCan->Init.NominalTimeSeg1 		= 155;		/* NTSEG1 1..256, NominalTimeSeg1 = Propagation_segment + Phase_segment_1 */
	phCan->Init.NominalTimeSeg2 		= 4; 		/* NTSEG2 1..128 */
	phCan->Init.NominalSyncJumpWidth 	= 3; 		/* NSJW   1..128 should be < NTSEG2 */
#endif
 
/* data = data phase with bit rate switching
 *	DBTP
 * 	80 MHz: tq = DataPrescaler x (1/fdcan_ker_ck)
 *		->  tq = 12.5 ns
 *	data rate = 1 / ((SyncSeg + Seg1 + Seg2) * tq)
 *		with SyncSeg = 1
 */
	phCan->Init.DataPrescaler 			= 1;		/* DBRP 1..32 */
 
	/* 8 Mbps = 10 * tq -> TimeSeg1 + TimeSeg2 = 9 */
	if( u32DataRate == 8 )
	{
		phCan->Init.DataTimeSeg1 			= 7;		/* NTSEG1 1..32, NominalTimeSeg1 = Propagation_segment + Phase_segment_1 */
		phCan->Init.DataTimeSeg2 			= 2;        /* NTSEG2 1..16 */
		phCan->Init.DataSyncJumpWidth 		= 2;        /* NSJW   1..16 should be < NTSEG2 */
	}
	/* 4 Mbps = 20 * tq -> TimeSeg1 + TimeSeg2 = 19 */
	else if( u32DataRate == 4 )
	{
		phCan->Init.DataTimeSeg1 			= 12;		/* NTSEG1 1..32, NominalTimeSeg1 = Propagation_segment + Phase_segment_1 */
		phCan->Init.DataTimeSeg2 			= 7;        /* NTSEG2 1..16 */
		phCan->Init.DataSyncJumpWidth 		= 5;        /* NSJW   1..16 should be < NTSEG2 */
	}
	/* 2 Mbps = 40 * tq -> TimeSeg1 + TimeSeg2 = 39 */
	else
	{
		phCan->Init.DataTimeSeg1 			= 24;		/* NTSEG1 1..32, NominalTimeSeg1 = Propagation_segment + Phase_segment_1 */
		phCan->Init.DataTimeSeg2 			= 15;       /* NTSEG2 1..16 */
		phCan->Init.DataSyncJumpWidth 		= 14;       /* NSJW   1..16 should be < NTSEG2 */
	}
 
	/* start pos in RAM of 2560 32-bit words */
	phCan->Init.MessageRAMOffset 		= 0;
 
	phCan->Init.StdFiltersNbr 			= 16;
	phCan->Init.ExtFiltersNbr 			= 16;
 
	phCan->Init.RxFifo0ElmtsNbr 		= 16;
	phCan->Init.RxFifo0ElmtSize 		= FDCAN_DATA_BYTES_64;
 
	phCan->Init.RxFifo1ElmtsNbr 		= 16;
	phCan->Init.RxFifo1ElmtSize 		= FDCAN_DATA_BYTES_64;
 
	phCan->Init.RxBuffersNbr 			= 16;
	phCan->Init.RxBufferSize 			= FDCAN_DATA_BYTES_64;
 
	phCan->Init.TxEventsNbr 			= 0;
	phCan->Init.TxBuffersNbr 			= 4;
	phCan->Init.TxFifoQueueElmtsNbr 	= 4;
	phCan->Init.TxFifoQueueMode 		= FDCAN_TX_FIFO_OPERATION;
	phCan->Init.TxElmtSize 				= FDCAN_DATA_BYTES_64;
 
	if( HAL_FDCAN_Init(phCan) != HAL_OK ) Error_Handler_FL(__FILE__, __LINE__);
 

Hi @Community member​,

I've heard back from the FDCAN expert regarding the documentation, and the confirmation that there is no bug and RM0468/Rev3 is accurate on this topic.

To elaborate further using Figure 772 Bit Timing, which can be found on page 2528/3357 of the RM0468/Rev 3 document.

0693W00000aIZp4QAG.jpg Bit timing = SyncSeg + BS1 + BS2

Where:

  1. SyncSeg = (1 x tq) as mentioned in 61.4.4 Bit timing, page. 2528

Synchronization segment (SYNC_SEG): a bit change is expected to occur within this

time segment, that has a fixed length of one time quantum (1 x tq).

  1. tBS1 = (DTSEG1 + 1) x tq.
  2. tBS2 = (DTSEG2 + 1) x tq.

as mentionned 61.5.3 FDCAN data bit timing and prescaler register (FDCAN_DBTP), 2566/3357

0693W00000aIZpTQAW.jpgBased on the information provided above,

             Bit timing = (1 x tq) + (DTSEG1 + 1) x tq + (DTSEG2 + 1) x tq.

  • Is equal to Bit timing = (DTSEG1 + DTSEG2 + 3) x tq as already mentioned in DBTP reg description, page 2567:

Therefore the length of the bit time is (DTSEG1 + DTSEG2 + 3) tq for programmed values.

 0693W00000aIZpYQAW.jpg 

Hope this clear and answer your question.

Imen

When your question is answered, please close this topic by clicking "Accept as Solution".
Thanks
Imen

Ouch, now I got it. So taking the increments from the 2 register values plus the Sync_Seg is 3... That was my fault, no documentation error.

@Imen DAHMEN​  Thanks for clarifying! And sorry for that!

Still, the 8 Mbit problem persists, any news on that?

I checked my timing settings, they are okay.

And as I said, it works up to 4 Mbit, but at 8 Mbit only with one of the FDCANs in external loopback mode.

As FDCAN1 is currently working correctly in FDCAN_MODE_EXTERNAL_LOOPBACK at 8Mbps.

So, I suggest testing FDCAN2 in EXTERNAL_LOOPBACK mode at 8Mbps and not in normal mode. This test could help identify if the problem is related to the Transceiver side, as it may not be able to reach 8Mbps.

0693W00000aIbnLQAS.png 

Imen

When your question is answered, please close this topic by clicking "Accept as Solution".
Thanks
Imen

@Imen DAHMEN​ 

I already tried that:

no matter if FDCAN 1 or 2, as long as one is in external loopback mode, BOTH are working with 8 Mbit.

So basically the transceivers are working, and somehow the peripherals, too.

I checked it also on the scope, and it's really 8 Mbit.

Isn't there anybody at ST who can grab a H735 DK and test that?

Just talking FDCAN1 with FDCAN2 at 8 Mbit.

LCE
Principal

So here are some screenshots from my (ancient) scope.

Pic 1: one of the 2 FDCANs (doesn't matter which) is in external loop mode, this one can transmit 8M data, the other FDCAN receives data correctly

Pic 2: FDCAN in normal mode - but "alone on the bus", instead of 8M data there's only "dominant" level = 0V (for the yellow "+" side); FDF, res and BRS bits are okay.

Pic 3: both FDCANs in normal mode, instead of 8M data there's only "dominant" level = 0V (for the yellow "+" side); FDF, res and BRS bits are okay.

Here the "dominant" level at data time drops even lower, as if both FDCANs pull it down.

Pic 1:

0693W00000aIgQpQAK.pngPic 2:

0693W00000aIgRYQA0.pngPic 3:

0693W00000aIgRiQAK.png 

LCE
Principal

... and here are the PSR & ECR registers:

after sending a message with one of the FDCANs in external loop mode:

  • both FDCANs indicate they have received a message with bit rate switching: PRS = 0x0000300F; bits REDL and RBRS are set
  • ECR = 0 -> no errors

That's how it should be, I'd say.

**************************************************

after sending a message with both of the FDCANs in normal mode - all other settings exactly the same:

sender:

  • PSR = 0x0000050F
    • DLEC (data last error code) = 5 -> error: bit 0
  • ECR = 0x00010008
    • 8 TX errors

receiver:

  • PSR = 0x0000020F
    • DLEC = 2 -> error: format
  • ECR = 0x00010100
    • 1 RX error

LCE
Principal

@Imen DAHMEN​  some more input above, oscilloscope screenshots and PSR & ECR registers

PHryn
Associate III

While ago I worked with G431 and 8M fdcan. You can try my calculator

from here https://phryniszak.github.io/stm32g-fdcan/

It worked for me but I dont know if FDCAN is the same as in STM32H7

@PHryn​ Thanks, very nice tool!

But unfortunately, even with the timings from your tool, the problem is still the same.