2023-02-27 08:48 AM
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 ?
Solved! Go to Solution.
2023-03-16 02:50 AM
Anybody? H7, 2 FDCANs, 8 Mbit ... ?
2023-03-16 03:27 AM
Send me two boards https://ie.farnell.com/stmicroelectronics/stm32h7b3i-dk/discovery-kit-arm-cortex-m7/dp/3297730 I do it for you.
2023-03-16 03:29 AM
:D good one!
You actually need only one board with 2 FDCANs to replicate my problem.
2023-03-16 08:46 AM
Just tested TDC - transceiver delay loop compensation.
With TDC enabled:
Is there something that I oversaw that TDC in general does not work with bit rate switching?
2023-03-16 11:22 AM
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
2023-03-16 12:53 PM
/**
* @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);
}
2023-03-17 05:06 AM
@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.