Skip to main content
LCE
Principal II
February 27, 2023
Solved

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

  • February 27, 2023
  • 14 replies
  • 8235 views

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 ?

This topic has been closed for replies.
Best answer by Tesla DeLorean

What are you doing with transmitter delay compensation? Surely things get a lot tighter when looking for signals coming back at higher speeds.

Check also status/error flagging in these conditions.

HAL_FDCAN_ConfigTxDelayCompensation : Configure the transmitter delay HAL_FDCAN_EnableTxDelayCompensation : Enable the transmitter delay compensation

https://community.st.com/s/question/0D53W00000AZ8prSAD/can-fd-error-status

14 replies

LCE
LCEAuthor
Principal II
February 28, 2023

I just checked the register values again and they were wrong, so above are the "correct" values.

Still the same problem:

2 Mbps perfect,

8 Mbps not working

Any ideas?

Is the input clock fdcan_ker_ck = 80 MHz too low?

Shouldn't be, ST's 2 Mbps examples use 20 MHz, and at VOS1 max FDCAN clock is 100 MHz.

Edit: 4 Mbps is working with:

DBRP  = 1

DTSEG1 = 12

DTSEG2 = 7

 DSJW  = 5

LCE
LCEAuthor
Principal II
February 28, 2023

Documentation, RM0468, latest edition:

61.4.4 Bit timing, pg. 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).

DBTP reg description, page 2567:

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

Same descr. in NBTP.

So, which one is correct, or are these 2 different things?

@Imen DAHMEN​ please?

Edit: Same in G4 RM

ST Technical Moderator
March 2, 2023

Hello @LCE (Community Member)​ ,

Thank you for your contribution.

I will escalate this issue internally to the FDCAN experts and I'll make sure to post more details here as soon as I hear back from our team.

Imen

In order to give better visibility on the answered topics, please click on 'Best answer' on the reply which solved your issue or answered your question. Thanks
LCE
LCEAuthor
Principal II
March 2, 2023

@Imen DAHMEN​ 

Thanks!

Anyway, note the documentation bug in DBTP and NBTP registers.

I'm pretty sure now that the +1 for the bit time is the correct value (instead of the +3).

LCE
LCEAuthor
Principal II
February 28, 2023

Anybody getting 8 Mbps on a H735 ?

At least someone from @ ST ever got that working?

I tried all kinds of timings, and I can't imagine that the CCU is needed, especially when communicating only with another on-chip FDCAN with the same timing settings.

Or this the problem, trying to have 2 FDCANs running with 8 Mbps at the same time?

LCE
LCEAuthor
Principal II
February 28, 2023

This is almost funny...

When I set FDCAN1 Mode to FDCAN_MODE_EXTERNAL_LOOPBACK, it sends with 8 Mbps, and FDCAN2 receives data correctly.

When I set FDCAN2 back to FDCAN_MODE_NORMAL, no 8 Mbps on the scope, no Rx on FDCAN2.

Then I get in FDCAN1:

PSR = 0000050F
 TDVC = 0 mtq
 PXE = 0
 REDL = 0
 RBRS = 0
 RESI = 0
 DLEC = 05 -> error: bit 0
 BO = 0
 EW = 0
 EP = 0
 ACT = 01 idle
 LEC = 07 -> error: no change
ECR = 00010008
 CEL = 1 CAN error log
 RP = 0
 REC = 0 RX err
 TEC = 8 TX err

LCE
LCEAuthor
Principal II
March 1, 2023

8 Mbit still not working (except ext loopback).

Checked again RM and DS, no specs concerning data rate.

Anybody?

@Peter BENSCH​  maybe?

Peter BENSCH
ST Technical Moderator
March 1, 2023

@Community member​ Thank you for your trust, but for once, due to lack of experience, I have nothing to contribute here.

Regards

/Peter

In order 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.
LCE
LCEAuthor
Principal II
March 2, 2023

@Peter BENSCH​  Thanks for your reply, at least something! :)

Maybe you can forward this question to your FDCAN experts?

It's really strange, everthing working fine up to 4 Mbit/s on both peripherals, but as I described: 8 Mbit works only in external loopback mode.

LCE
LCEAuthor
Principal II
March 7, 2023

@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__);
 

LCE
LCEAuthor
Principal II
March 10, 2023

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
LCEAuthor
Principal II
March 10, 2023

... 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
LCEAuthor
Principal II
March 10, 2023

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

PHryn
Associate III
March 12, 2023

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

LCE
LCEAuthor
Principal II
March 13, 2023

@PHryn​ Thanks, very nice tool!

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