Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CandleLight FD at 8 Mbps #173

Open
tomasjakubik opened this issue Dec 22, 2023 · 3 comments
Open

CandleLight FD at 8 Mbps #173

tomasjakubik opened this issue Dec 22, 2023 · 3 comments

Comments

@tomasjakubik
Copy link

This issue is specifically with candleLight FD and fork topic/candleLightFD, but that doesn't allow issues.

We are starting a CAN FD project. We bought some candleLight FDs to debug and perhaps to manage the network from Linux. The issue is that this firmware doesn't compensate for transceiver delay and so it cannot transmit over about 2 Mbps. Receive works fine with 1 & 8 Mbps, but when you try transmitting, the FDCAN peripheral cannot verify the bits it sent, fails, repeats and fails again.
Without Tx delay compensation, my code was behaving in a similar way. Here is some code that works for me on G4 nucleo clocked at 160 MHz:

        hfdcan2.Instance = FDCAN2;
        hfdcan2.Init.ClockDivider = UINT32_MAX; // Divider is not available for FDCAN2
        hfdcan2.Init.FrameFormat = FDCAN_FRAME_FD_BRS;
        hfdcan2.Init.Mode = FDCAN_MODE_NORMAL;
        hfdcan2.Init.AutoRetransmission = ENABLE;
        hfdcan2.Init.TransmitPause = ENABLE;
        hfdcan2.Init.ProtocolException = ENABLE;
        hfdcan2.Init.NominalPrescaler = 1;
        hfdcan2.Init.NominalSyncJumpWidth = 32;
        hfdcan2.Init.NominalTimeSeg1 = 127;
        hfdcan2.Init.NominalTimeSeg2 = 32;
        hfdcan2.Init.DataPrescaler = 1;
        hfdcan2.Init.DataSyncJumpWidth = 4;
        hfdcan2.Init.DataTimeSeg1 = 15;
        hfdcan2.Init.DataTimeSeg2 = 4;
        hfdcan2.Init.StdFiltersNbr = 0;
        hfdcan2.Init.ExtFiltersNbr = 0;
        hfdcan2.Init.TxFifoQueueMode = FDCAN_TX_QUEUE_OPERATION;
        if (HAL_FDCAN_Init(&hfdcan2) != HAL_OK) {
            Error_Handler();
        }

        // Set TIM3 as source of the timestamp
        if (HAL_FDCAN_EnableTimestampCounter(&hfdcan2, FDCAN_TIMESTAMP_EXTERNAL) != HAL_OK) {
            Error_Handler();
        }

        /// @note Configure Tx delay compensation of the used transceiver for high speed data phase.
        ///   FDCAN automatically measures delay between falling edge on FDCAN_TX and FDCAN_RX.
        ///
        /// TdcOffset:
        ///   This is a value to be added to the measured delay. FDCAN measures delay between falling edges.
        ///   TdcOffset is added to the measured delay to get in the middle of the bit.
        ///   Documentation sucks. Nobody knows what minimal time quanta is. More info could be probably in CiA 601-2 which is paywalled.
        ///   Seems like minimal time quanta is the master CAN clock. Note that CAN2 doesn't have divider.
        ///
        ///   The value used was found experimentally for 1 & 8 Mbps and TJA1051/T3 transceiver.
        ///   Delay between FDCAN_TX and FDCAN_RX measured by logic analyzer is approximately 100 ns.
        ///   Values from 5 to 20 worked. At 160 MHz the length 20 * 6.25 ns = 125 ns or one bit.
        ///   Perhaps the offset needs to be between 25% and 100% of the bit length.
        ///   Of the working interval, 75% was used (80% of the bit); TdcOffset = 16.
        ///
        /// TdcFilter:
        ///   This is a minimal value for the measured delay. It prevents glitch on Rx to trigger too early.
        ///
        ///   The value used was found experimentally for 1 & 8 Mbps and TJA1051/T3 transceiver.
        ///   When the transceiver is working at correct speed, the value from PSR/TDCV register was read; TDCV = 30.
        ///   Of that value, 75% was used; TdcFilter = 22.
        if (HAL_FDCAN_ConfigTxDelayCompensation(&hfdcan2, 16, 22) != HAL_OK) {
            Error_Handler();
        }
        if (HAL_FDCAN_EnableTxDelayCompensation(&hfdcan2) != HAL_OK) {
            Error_Handler();
        }

This is not ready to be a pull request. It will need different values at different speeds. Unfortunately, the documentation I have available is not good enough to have a proper solution.
When I have Tag-Connect I may have a more deeper look into the firmware, but I cannot promise anything.

I guess that you are in process of merging the fork here, but any ideas on how or even if it should be incorporated into the firmware?

@marckleinebudde
Copy link
Contributor

Hey @tomasjakubik,

I've cherry-picked and squashed @pgreenland's commit pgreenland@4051608 into my https://github.com/marckleinebudde/candleLight_fw/tree/multichannel branch. Can you test, if this fixes your problem?

Cc: @lichtfeind

@tomasjakubik
Copy link
Author

Hi, thanks. Now I can communicate at full 8 Mbps.

I missed that post on ST forum. Good idea to use DataTimeSeg1*DataPrescaler as the TdcOffset value. It should fit no matter the settings.

@tomasjakubik
Copy link
Author

Maybe I spoke too soon. I think it can get stuck.

There is nothing wrong on the bus. Other devices communicate without issues. Rx and Tx LEDs do not blink. When trying to manually send something, cansend says write: No buffer space available. Nothing in dmesg. It starts working again when unplugged and replugged again.
I have seen it several times and not once with firmware the candleLight FD had from factory.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants