Re: [RFC] Add new CAN FD bittiming parameters: Transmission Delay Compensation (TDC)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello Oliver,

On Sat. 16 Jan 2021 à 19:41, Oliver Hartkopp <socketcan@xxxxxxxxxxxx> wrote:
>
> Hello Vincent,
>
> I like this separate struct too.
>
> On 16.01.21 08:02, Vincent Mailhol wrote:
> > This RFC is a follow-up on the discussion started in:
> > https://lore.kernel.org/linux-can/20210112130538.14912-1-mailhol.vincent@xxxxxxxxxx/T/#t
> >
> > * Scope of this RFC *
> >
> > I want to discuss 1/ which TDC values we should provide to the
> > user and 2/ how to calculate those. In this RFC, I will not
> > directly discuss how to actually modify the netlink ABI.
> >
> >
> > * The code *
> >
> > /**
> >   * struct can_tdc - CAN FD Transmission Delay Compensation parameters
> >   *
> >   * At high bit rates, the propagation delay from the TX pin to the RX
> >   * pin of the transceiver causes measurement errors and needs to be
> >   * corrected.
> >   *
> >   * To solve this issue, ISO 11898-1 introduces in section 11.3.3
> >   * "Transmitter delay compensation" a SSP (Secondary Sample Point)
> >   * equal to the distance, in time quanta, from the start of the bit
> >   * time to the measurement on the RX pin.
> >   *
> >   * This structure contains the parameters to calculate that SSP.
> >   *
> >   * @tdcv: Transmitter Delay Compensation Value. Distance, in time
>
> would name it @tdc without 'v' as you already have it in your struct below.

Both the MCP251XXFD-CAN-FD and the Microchip CAN FD Controller
Module use this naming for their register.

Throughout the documents, I also encountered "Transmitter Delay
Value" or just "Transmitter Delay" to designate that value (but
not as a register name). I do not recall seeing "Transmitter
Delay Compensation" to designate the value: this nomination is
rather used for the full concept (i.e. the name of the structure).

I myself am not a huge fan of the tdcv but I still prefer to use
it to follow the trend. If you insist to shorten it, I would
prefer to use tdv for "Transmitter Delay Value".

The tdc in my struct below was a typo. I meant to also name it tdcv.

> >   *    quanta, from when the bit is sent on the TX pin to when it is
> >   *    received on the RX pin of the transmitter.
> >   *
> >   *    0: Automatic mode (default). Use the value dynamically
> >   *    measured by the controller.
> >   *
> >   *    Other values: manual mode. Use the fixed provided value.
> >   *
> >   *    N.B. when using the automatic mode, the dynamically measured
> >   *    value might not be visible to the kernel.
> >   *
> >   * @tdco: Transmitter Delay Compensation Offset. Offset value, in time
> >   *    quanta, defining the delay between the start of the bit
> >   *    reception on the CANRX pin of the transceiver and the SSP such
> >   *    as SSP = @tdcv + @tdco.
>
> SSP = @tdc + @tdco.
>
> >   *
> >   * @tdcf: Transmitter Delay Compensation Filter window. Defines the
>
> @tdcw: Transmitter Delay Compensation Window.
>
> The value describes the window (of a filter).

Same here, the microcontrollers which use this feature all tend to
name their register tdcf. I prefer not to deviate from the existing.

> >   *    minimum value for the SSP position, in time quanta. If SSP is
> >   *    less than @tdcf, then no compensation delay occurs and the
> >   *    normal sampling point is used instead. The feature is enabled
> >   *    if and only if @tdcf is configured to a value greater than @tdco.
> >   */
> > struct can_tdc {
> >      u16 tdc;

As written above, this is a typo. I meant:
u16 tdcv;

> >      u16 tdco;
> >      u16 tdcf;
> > };
>
>
> Currently all these kind of values are __u32:
>
> https://elixir.bootlin.com/linux/v5.11-rc3/source/include/uapi/linux/can/netlink.h#L31
>
> Shouldn't we stick on this pattern here?
>
> struct can_tdc {
>          __u32 tdc;

__u32 tdcv;

>          __u32 tdco;
>          __u32 tdcw;
> };

Based on current value: yes. I used u16 as an anticipation of the
modification that will be done on the netlink interface. Once we
have a dedicated kernel only bittiming structure for the kernel,
we will have more freedom and could save a few bytes.

Nonetheless, this is a discussion we can have when actually doing
the netlink modification. For now, I am fine to use __u32.

> > /**
> >   * struct can_tdc_const - CAN hardware-dependent bit-timing constant
> >   *    for TDC
> >   *
> >   * @tdcv_max: Transmitter Delay Compensation Value maximum value,
> >   *    should be set to zero if the controller does not support
> >   *    manual mode for tdcv.
> >   * @tdco_max: Transmitter Delay Compensation Offset maximum value.
> >   *    Should be set to zero if the controller does not support TDC.
> >   * @tdcf_max: Transmitter Delay Compensation Filter window maximum
> >   *    value. Should be set to zero if the controller does not
> >   *    support this feature.
> >   */
> > struct can_tdc_const {
> >      u16 tdcv_max;
> >      u16 tdco_max;
> >      u16 tdcf_max;
> > };
>
> Same question here with naming and __u32 data structure.

Ack, OK for __32 for the moment.

> Regards,
> Oliver
>
> >
> > /* Do the bittiming calculation of the tdc parameters */
> > static void can_set_tdc(const struct can_bittiming *dbt, struct can_tdc *tdc,
> >              const struct can_tdc_const *tdc_const)> > {
> >      /* As specified in ISO 11898-1 section 11.3.3 "Transmitter
> >       * delay compensation" (TDC) is only applicable if data BRP is
> >       * one or two.
> >       */
> >      if ((dbt->brp == 1) || (dbt->brp == 2)) {
> >          memset(tdc, 0, sizeof(*tdc));
> >          return;
> >      }
> >
> >      tdc->tdcv = 0;
> >      /* Convert the sample point from tenth of a percent to time quanta */
> >      tdc->tdco = min(can_bit_time(dbt) * dbt->sample_point / 100,
> >              tdc_const->tdco_max);
> >      tdc->tdcf = 0;
> > }
> >
> >
> > * Explanation on the code *
> >
> > The only way to calculate tdcv is through measurement which is
> > done by the controller. This parameter is only here to receive a
> > fixed value that would be given by the user through the netlink
> > interface.
> >
> > The calculation of tdco is of my conception. I could not find any
> > reference formula. My logic is to just reuse the normal sample
> > point so that at the end ssp = tdcv + sp.  Another method might
> > set ssp to the middle of the bit:
> >    tdc->tdco = can_bit_time(dbt) / 2
> >
> > My current proposal is not to use tdcf by default (leave it to
> > zero) if doing bittiming calculation. Meaning that this value
> > will only be used if configured by the user through the netlink
> > interface. The reason for this choice are:
> >    * the lack of test environment: on my hardware (the ETAS
> >      ES582.1), everything works up fine to 8 Mbps just by using
> >      the tdco.
> >    * I could not find a good reference to calculate that value.
> > Any ideas of how to calculate tdcf is welcome!
> >
> >
> > * References *
> >
> > This is a collection of specifications and references which I
> > used while writing this RFC. I believe that all TDC use cases are
> > covered in this RFC.
> >
> >    - Bosch C_CAN FD8:
> > https://www.bosch-semiconductors.com/media/ip_modules/pdf_2/c_can_fd8/users_manual_c_can_fd8_r210_1.pdf
> >
> >    - Microchip CAN FD Controller Module:
> > http://ww1.microchip.com/downloads/en/DeviceDoc/MCP251XXFD-CAN-FD-Controller-Module-Family-Reference-Manual-20005678B.pdf
> >
> >    - SAM E701/S70/V70/V71 Family:
> > https://www.mouser.com/datasheet/2/268/60001527A-1284321.pdf
> >
> >    - ISO 11898-1
> >
> >
> > Thank you for your comments,
> >
> >
> > Yours sincerely,
> > Vincent
> >




[Index of Archives]     [Automotive Discussions]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux]     [Linux OMAP]     [Linux MIPS]     [eCos]     [Asterisk Internet PBX]     [Linux API]     [CAN Bus]

  Powered by Linux