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

Anybody? H7, 2 FDCANs, 8 Mbit ... ?

PHryn
Associate III

:D good one!

You actually need only one board with 2 FDCANs to replicate my problem.

LCE
Principal

Just tested TDC - transceiver delay loop compensation.

With TDC enabled:

  • 8M with ext. loopback does NOT work anymore
  • 4M and 2M normal mode does NOT work anymore

Is there something that I oversaw that TDC in general does not work with bit rate switching?

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

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
/**
  * @brief  Initialize FDCAN modules and configure Rx filters and Tx messages
  * @param  None
  * @retval None
  */
static void Config_FDCAN(void)
{
  /*                     Bit time configuration:
    Bit time parameter         | Nominal      |  Data
    ---------------------------|--------------|------------------
    fdcan_ker_ck               | 80 MHz       | 80 MHz
    Time_quantum (tq)          | 12.5 ns      | 12.5 ns
    Synchronization_segment    | 1 tq         | 1 tq
    Propagation_segment        | 47 tq        | 1 tq
    Phase_segment_1            | 16 tq        | 4 tq
    Phase_segment_2            | 16 tq        | 4 tq
    Synchronization_Jump_width | 16 tq        | 4 tq
    Bit_length                 | 80 tq = 1 µs | 10 tq = 0.125 µs
    Bit_rate                   | 1 MBit/s     | 8 MBit/s
  */
  hfdcan.Instance = FDCANx;
  hfdcan.Init.FrameFormat = FDCAN_FRAME_FD_BRS;
  hfdcan.Init.Mode = FDCAN_MODE_NORMAL;
  hfdcan.Init.AutoRetransmission = ENABLE;
  hfdcan.Init.TransmitPause = DISABLE;
  hfdcan.Init.ProtocolException = ENABLE;
  hfdcan.Init.NominalPrescaler = 0x1; /* tq = NominalPrescaler x (1/fdcan_ker_ck) */
  hfdcan.Init.NominalSyncJumpWidth = 0x10;
  hfdcan.Init.NominalTimeSeg1 = 0x3F; /* NominalTimeSeg1 = Propagation_segment + Phase_segment_1 */
  hfdcan.Init.NominalTimeSeg2 = 0x10;
  hfdcan.Init.DataPrescaler = 0x1;
  hfdcan.Init.DataSyncJumpWidth = 0x4;
  hfdcan.Init.DataTimeSeg1 = 0x5; /* DataTimeSeg1 = Propagation_segment + Phase_segment_1 */
  hfdcan.Init.DataTimeSeg2 = 0x4;
  hfdcan.Init.MessageRAMOffset = 0;
  hfdcan.Init.StdFiltersNbr = 1;
  hfdcan.Init.ExtFiltersNbr = 0;
  hfdcan.Init.RxFifo1ElmtsNbr = 0;
  hfdcan.Init.TxEventsNbr = 0;
  hfdcan.Init.RxBuffersNbr = 1;
  hfdcan.Init.RxBufferSize = FDCAN_DATA_BYTES_8;
  hfdcan.Init.RxFifo0ElmtsNbr = 0;
  hfdcan.Init.TxBuffersNbr = 0;
  hfdcan.Init.TxFifoQueueElmtsNbr = 16;
  hfdcan.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION;
  hfdcan.Init.TxElmtSize = FDCAN_DATA_BYTES_64;
 
  /* Initializes the FDCAN module */
  HAL_FDCAN_Init(&hfdcan);
 
  /* Configure Rx filter to receive synchronization message */
  sFilterConfig.IdType = FDCAN_STANDARD_ID;
  sFilterConfig.FilterIndex = 0;
  sFilterConfig.FilterConfig = FDCAN_FILTER_TO_RXBUFFER;
  sFilterConfig.FilterID1 = 0x111;
  sFilterConfig.RxBufferIndex = 0;
  sFilterConfig.IsCalibrationMsg = 0;
  HAL_FDCAN_ConfigFilter(&hfdcan, &sFilterConfig);
 
  /* Prepare Tx image data message header */
  TxHeader.Identifier = 0x001;
  TxHeader.IdType = FDCAN_STANDARD_ID;
  TxHeader.TxFrameType = FDCAN_DATA_FRAME;
  TxHeader.DataLength = FDCAN_DLC_BYTES_64;
  TxHeader.ErrorStateIndicator = FDCAN_ESI_ACTIVE;
  TxHeader.BitRateSwitch = FDCAN_BRS_OFF;
  TxHeader.FDFormat = FDCAN_FD_CAN;
  TxHeader.TxEventFifoControl = FDCAN_NO_TX_EVENTS;
  TxHeader.MessageMarker = 0;
 
  /* Configure and enable Tx Delay Compensation : TdcOffset = DataTimeSeg1*DataPrescaler */
  HAL_FDCAN_ConfigTxDelayCompensation(&hfdcan, 5, 0);
  HAL_FDCAN_EnableTxDelayCompensation(&hfdcan);
}

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
LCE
Principal

@Community member​ 

Man, you nailed it! BIG THANKS!

I "played" with TDC, but I thought it's completely automatic, I didn't understand that I still have to set the offset for the SSP.

So embarrassing for me...

But also ST - if one person from ST knowing the FDCAN peripheral would have taken a look at my setup, not finding any TDC offset settings... or just could have given me the hint about taking a look at TDC.