-
Notifications
You must be signed in to change notification settings - Fork 650
Bit timing config for PCAN #625
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
Conversation
Codecov Report
@@ 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 Report
@@ 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 |
@bmeisels, could you have a look at this and tell me what you think? |
@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! |
I must have missed that note, where is it?
I agree. I just wanted to gather the deprecated code to one place and make it match with the class section.
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. |
The note I mentioned is on the PCAN code in the PR. You can see it above in this page. |
Have you submitted the review? |
if f_clock_val is None: | ||
f_clock = "{}={}".format("f_clock_mhz", kwargs.get("f_clock_mhz", None)) | ||
params = {} | ||
if timing and data_timing: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think there should be a single timing object which includes both arbitration and data timings.
This also solves the problem of multiple f_clock settings.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you mean that the class should handle both arbitration and data timings I'm not sure I agree about that. Apart from f_clock (which is not always required), everything else would have to be duplicated or require some overly complex code structures in that class. There would also need to be separate classes for CAN-FD and regular CAN to not add confusion for most users which do not use CAN-FD.
This solution does not need to consider if the timing settings are used for normal CAN, arbitration phase or data phase since they are basically the same and have no dependency apart from clock frequency and can therefore be specified separately.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see why this will complicate the usage as long as the data phase timings are optional.
Just to make sure we share the same understanding. Normal timings aka nom are used for both arbitration and data in standard CAN. Data timings are only used in CAN-FD for the data phase.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For standard CAN there is no nominal or arbitration or data timing, just timing. I don’t think it makes sense to force CAN-FD nomenclature on standard CAN users, especially when the interfaces don’t even support CAN-FD.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't agree. The data timing are only used when the bit rate switch flag is marked. This means that the nominal bit timings have generally the same meaning as in classic CAN (and technically can be used with classic CAN on the same bus as long as the CAN ICs are FD bus compatible, even if they don't support the FD extensions). The data timings are the addition. The Peak software tools seem to treat the timings as I have described.
I don't see how this is forcing anything on classic CAN users. If you think the naming is clearer the way it is now I would add the data timings and not add the nominal prefix to the existing timings.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about this? Since timings are then grouped by prefix there is no added value for the user to have a separate class for specifying timing values. They can enter them into the Bus constructor directly. Internally we can construct BitTiming instances however using some utility function taking a bunch of kwargs and returning a nominal and data timing objects.
I must have missed it somehow. |
#615 is now merged. |
@christiansandberg Can this now be finalized? |
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). |
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 The one restriction that 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 @christiansandberg |
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 # 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) |
Had a look at this again.
I strongly prefer 1 and would like to hear other opinions. |
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 The interface implementations could just pass their 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. |
This is tagged to be included in |
@felixdivo @christiansandberg I think the third option should be ok. 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? |
Agreed. However, I haven't touched the PCAN or CAN FD stuff so I'd rather not change anything there. |
I'll start doing some implementation but I don't have any hardware access either. |
I could do some testing with PCAN-USB FD adapters, just let me know :) |
Superseded by #1514 |
@zariiii9003 Should we keep this branch? |
@felixdivo deleted. I usually don't delete branches of other maintainers 😄 |
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. |
Depends on #615 to be merged first.Fixes #538.
Part of #614.