python-can icon indicating copy to clipboard operation
python-can copied to clipboard

Bit timing config for PCAN

Open christiansandberg opened this issue 6 years ago • 21 comments
trafficstars

~Depends on #615 to be merged first.~ Fixes #538. Part of #614.

christiansandberg avatar Jun 16 '19 19:06 christiansandberg

Codecov Report

Merging #625 (22dc9e3) into develop (6c01b3c) will decrease coverage by 0.24%. The diff coverage is 2.77%.

@@             Coverage Diff             @@
##           develop     #625      +/-   ##
===========================================
- Coverage    70.41%   70.17%   -0.25%     
===========================================
  Files           72       72              
  Lines         7123     7148      +25     
===========================================
  Hits          5016     5016              
- Misses        2107     2132      +25     

codecov[bot] avatar Jun 16 '19 19:06 codecov[bot]

Codecov Report

Merging #625 into develop will increase coverage by 1.68%. The diff coverage is 2.85%.

@@             Coverage Diff             @@
##           develop     #625      +/-   ##
===========================================
+ Coverage    61.99%   63.67%   +1.68%     
===========================================
  Files           63       63              
  Lines         5623     5644      +21     
===========================================
+ Hits          3486     3594     +108     
+ Misses        2137     2050      -87

codecov[bot] avatar Jun 16 '19 19:06 codecov[bot]

@bmeisels, could you have a look at this and tell me what you think?

christiansandberg avatar Jun 16 '19 20:06 christiansandberg

@christiansandberg, I've been following your work on #615 and it looks very promising. See my note about unifying arbitration and data timings.

As a general note I think my parameter list parsing is a bit cleaner compared to the change you made but as this will be removed in the future I think this is more of a style issue. I still think there is some cleanup that can be done.

Also it seems you dropped support for f_clock_mhz when using the timing class. For PCAN i don't think this matters but I am not sure about other interfaces.

I will try and test the code on my setup later this week.

Keep up the good work!

bmeisels avatar Jun 16 '19 20:06 bmeisels

See my note about unifying arbitration and data timings.

I must have missed that note, where is it?

As a general note I think my parameter list parsing is a bit cleaner compared to the change you made but as this will be removed in the future I think this is more of a style issue. I still think there is some cleanup that can be done.

I agree. I just wanted to gather the deprecated code to one place and make it match with the class section.

Also it seems you dropped support for f_clock_mhz when using the timing class. For PCAN i don't think this matters but I am not sure about other interfaces.

It is just a convenience parameter so I thought it might add more confusion to have multiple ways of specifying the frequency. SI-units should be preferred.

christiansandberg avatar Jun 17 '19 10:06 christiansandberg

The note I mentioned is on the PCAN code in the PR. You can see it above in this page.

bmeisels avatar Jun 17 '19 14:06 bmeisels

Have you submitted the review?

christiansandberg avatar Jun 17 '19 17:06 christiansandberg

I must have missed it somehow.

bmeisels avatar Jun 18 '19 05:06 bmeisels

#615 is now merged.

felixdivo avatar Jun 23 '19 10:06 felixdivo

@christiansandberg Can this now be finalized?

felixdivo avatar Jul 14 '19 09:07 felixdivo

I would prefer to get some more input on how we want to have it first. Basically if we should use class instances to divide between normal and data phase timing or use prefixes (like now).

christiansandberg avatar Jul 14 '19 18:07 christiansandberg

I am in favour of using a seperate class, since that one could (a) do common validation on the parameters that would else need to be duplicated in some way and (b) it factors out a common group of parameters, making the construction of a bus instance more readable.

I also like the way timing is separate from data_timing, it serves the intuition that the data phase has different timing parameters and keeps things relatively simple.

The one restriction that f_clock is duplicated can be solved by a simple if-raise block, I don't see a problem there. That's a good compromise from my point of view.

But one thing is important; this should be handled the same way in all interfaces that use this new class, and we could probably add a not on this in the BitTiming class.

felixdivo avatar Jul 15 '19 07:07 felixdivo

@felixdivo @christiansandberg I still think we should consider adding a FDBitTiming class which will include both configurations. This would also allow us to remove the FD parameter as we could just check if the timing is a FD timing. I think this is much better than passing 2 timing object (like in #650) or only constructing them internally (as proposed by @christiansandberg).

bmeisels avatar Aug 04 '19 14:08 bmeisels

Maybe it is overkill exposing a class for this in the API. How about using dictionaries to group the timing parameters but having possibility to pass f_clock separately since it is common for both? Also the bitrate could be taken from the kwargs since that is the standard way to pass it when not using timing parameters.

# Specifying all parameters in the timing dictionary
can20_bus = can.Bus("channel", "interface",
    timing={bitrate=1000000, f_clock=8000000, tseg1=5, tseg2=2, sjw=1}
)

# Or specifying bitrate and f_clock in kwargs
can20_bus = can.Bus("channel", "interface",
    bitrate=1000000,
    f_clock=8000000,
    timing={tseg1=5, tseg2=2, sjw=1}
)

# CAN-FD buses also needs a data_timing dict for CAN-FD frames only while regular frames are unaffected
canfd_bus = can.Bus("channel", "interface",
    f_clock=80000000,
    timing={bitrate=500000, tseg1=119, tseg2=40, sjw=40},
    data_timing={bitrate=2000000, tseg1=29, tseg2=10, sjw=10}
)

Those will internally be constructed to BitTiming classes, using some utility function that all interfaces can use.

# A util function for constructing a BitTiming object
def get_bit_timing_object(timing=None, f_clock=None, bitrate=None):
    timing_args = dict(timing or {})
    timing_args.setdefault("bitrate", bitrate)
    timing_args.setdefault("f_clock", f_clock)
    return can.BitTiming(**timing_args)


class SomeBus:
    def __init__(self, bitrate=None, f_clock=None, timing=None, data_timing=None):
        # Create a timing object from kwargs
        timing_obj = get_bit_timing_object(timing, f_clock, bitrate)
        # Optionally add CAN-FD data timing as well
        data_timing_obj = get_bit_timing_object(data_timing, f_clock)

christiansandberg avatar Jan 05 '20 19:01 christiansandberg

Had a look at this again. I see 2 options:

  1. Extend the bit timing class with optional timings for CAN FD. This will allow using a single class which can be passed around and should be transparent to users of standard CAN.
  2. Have 2 instances of timing and make sure to test that the f_clock is the same on both.

I strongly prefer 1 and would like to hear other opinions.

bmeisels avatar Aug 24 '20 09:08 bmeisels

I'd like to add a third option, which is for the user to pass all bit timing settings as individual keyword arguments just like they do today, but with standardized names (and with today's names as deprecated aliases). If you prefer to group the settings in one or more objects to pass around you can still do that using dictionaries and the **dict syntax to pass them on to the constructor.

The interface implementations could just pass their **kwargs to some helper function which returns BitTiming objects which can be used internally.

One reason I would not prefer option 1 is to keep the code DRY. All calculations would have to be duplicated although they do the same thing. Bit timing calculations are independent of whether it is for CAN, CAN-FD, arbitration or data.

christiansandberg avatar Aug 27 '20 17:08 christiansandberg

This is tagged to be included in Version 4.0, is this close to being merged? It seems like there isn't too much missing.

felixdivo avatar Nov 19 '20 15:11 felixdivo

@felixdivo @christiansandberg I think the third option should be ok. This would mean changing most of this PR.

I don't currently have time / convenient access to hardware on a daily basis but if someone spun up another version I would try to test it.

@christiansandberg what do you think?

bmeisels avatar Nov 22 '20 07:11 bmeisels

the third option should be ok

Agreed. However, I haven't touched the PCAN or CAN FD stuff so I'd rather not change anything there.

felixdivo avatar Nov 22 '20 11:11 felixdivo

I'll start doing some implementation but I don't have any hardware access either.

christiansandberg avatar Nov 24 '20 21:11 christiansandberg

I could do some testing with PCAN-USB FD adapters, just let me know :)

KloolK avatar Mar 15 '21 14:03 KloolK

Superseded by #1514

zariiii9003 avatar Feb 06 '23 08:02 zariiii9003

@zariiii9003 Should we keep this branch?

felixdivo avatar Feb 06 '23 08:02 felixdivo

@felixdivo deleted. I usually don't delete branches of other maintainers 😄

zariiii9003 avatar Feb 06 '23 08:02 zariiii9003

Thanks!

I'm also reluctant to do so, but I also think that fewer branches help others to maintain on overview over the project. 🙂 And besides, the diff is preserved in the PR.

felixdivo avatar Feb 06 '23 11:02 felixdivo