From 0c9b91f4fa813af0ce4e65f56af2c96a17069447 Mon Sep 17 00:00:00 2001 From: zariiii9003 <52598363+zariiii9003@users.noreply.github.com> Date: Sat, 28 Jan 2023 14:02:24 +0100 Subject: [PATCH 1/5] add copy button --- doc/conf.py | 1 + doc/doc-requirements.txt | 1 + 2 files changed, 2 insertions(+) diff --git a/doc/conf.py b/doc/conf.py index 6ba661a30..cea93440d 100755 --- a/doc/conf.py +++ b/doc/conf.py @@ -49,6 +49,7 @@ "sphinx.ext.graphviz", "sphinxcontrib.programoutput", "sphinx_inline_tabs", + "sphinx_copybutton", ] # Now, you can use the alias name as a new role, e.g. :issue:`123`. diff --git a/doc/doc-requirements.txt b/doc/doc-requirements.txt index c61b55683..9a01cf589 100644 --- a/doc/doc-requirements.txt +++ b/doc/doc-requirements.txt @@ -1,4 +1,5 @@ sphinx>=5.2.3 sphinxcontrib-programoutput sphinx-inline-tabs +sphinx-copybutton furo From 615fab8a7ad2e5d0735d24f0193b730aa91ca890 Mon Sep 17 00:00:00 2001 From: zariiii9003 <52598363+zariiii9003@users.noreply.github.com> Date: Sat, 28 Jan 2023 14:05:16 +0100 Subject: [PATCH 2/5] make bittiming classes hashable --- can/bit_timing.py | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/can/bit_timing.py b/can/bit_timing.py index 2dc78064b..989073ae9 100644 --- a/can/bit_timing.py +++ b/can/bit_timing.py @@ -395,14 +395,14 @@ def recreate_with_f_clock(self, f_clock: int) -> "BitTiming": def __str__(self) -> str: segments = [ - f"BR {self.bitrate} bit/s", + f"BR: {self.bitrate:_} bit/s", f"SP: {self.sample_point:.2f}%", f"BRP: {self.brp}", f"TSEG1: {self.tseg1}", f"TSEG2: {self.tseg2}", f"SJW: {self.sjw}", f"BTR: {self.btr0:02X}{self.btr1:02X}h", - f"f_clock: {self.f_clock / 1e6:.0f}MHz", + f"CLK: {self.f_clock / 1e6:.0f}MHz", ] return ", ".join(segments) @@ -425,6 +425,9 @@ def __eq__(self, other: object) -> bool: return self._data == other._data + def __hash__(self) -> int: + return tuple(self._data.values()).__hash__() + class BitTimingFd(Mapping): """Representation of a bit timing configuration for a CAN FD bus. @@ -999,7 +1002,7 @@ def recreate_with_f_clock(self, f_clock: int) -> "BitTimingFd": def __str__(self) -> str: segments = [ - f"NBR: {self.nom_bitrate} bit/s", + f"NBR: {self.nom_bitrate:_} bit/s", f"NSP: {self.nom_sample_point:.2f}%", f"NBRP: {self.nom_brp}", f"NTSEG1: {self.nom_tseg1}", @@ -1007,11 +1010,11 @@ def __str__(self) -> str: f"NSJW: {self.nom_sjw}", f"DBR: {self.data_bitrate} bit/s", f"DSP: {self.data_sample_point:.2f}%", - f"DBRP: {self.data_brp}", + f"DBRP: {self.data_brp:_}", f"DTSEG1: {self.data_tseg1}", f"DTSEG2: {self.data_tseg2}", f"DSJW: {self.data_sjw}", - f"f_clock: {self.f_clock / 1e6:.0f}MHz", + f"CLK: {self.f_clock / 1e6:.0f}MHz", ] return ", ".join(segments) @@ -1034,6 +1037,9 @@ def __eq__(self, other: object) -> bool: return self._data == other._data + def __hash__(self) -> int: + return tuple(self._data.values()).__hash__() + def _oscillator_tolerance_condition_1(nom_sjw: int, nbt: int) -> float: """Arbitration phase - resynchronization""" From 42a55c14a91db1707e3ad230d427ef96a831f596 Mon Sep 17 00:00:00 2001 From: zariiii9003 <52598363+zariiii9003@users.noreply.github.com> Date: Sat, 28 Jan 2023 14:05:51 +0100 Subject: [PATCH 3/5] add code example to show possible bit timings --- doc/bit_timing.rst | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/doc/bit_timing.rst b/doc/bit_timing.rst index b48a133b8..7c272d270 100644 --- a/doc/bit_timing.rst +++ b/doc/bit_timing.rst @@ -63,10 +63,38 @@ to specify custom bit timings. The :class:`~can.BitTiming` and :class:`~can.BitTimingFd` classes can be used for this purpose to specify bit timings in a relatively interface agnostic manner. +:class:`~can.BitTiming` or :class:`~can.BitTimingFd` can also help you to +produce an overview of possible bit timings for your desired bit rate: + + >>> import contextlib + >>> import can + ... + >>> timings = set() + >>> for sp in range(50, 100): + ... with contextlib.suppress(ValueError): + ... timings.add( + ... can.BitTiming.from_sample_point( + ... f_clock=8_000_000, + ... bitrate=250_000, + ... sample_point=sp, + ... ) + ... ) + ... + >>> for timing in sorted(timings, key=lambda x: x.sample_point): + ... print(timing) + BR: 250_000 bit/s, SP: 50.00%, BRP: 2, TSEG1: 7, TSEG2: 8, SJW: 4, BTR: C176h, CLK: 8MHz + BR: 250_000 bit/s, SP: 56.25%, BRP: 2, TSEG1: 8, TSEG2: 7, SJW: 4, BTR: C167h, CLK: 8MHz + BR: 250_000 bit/s, SP: 62.50%, BRP: 2, TSEG1: 9, TSEG2: 6, SJW: 4, BTR: C158h, CLK: 8MHz + BR: 250_000 bit/s, SP: 68.75%, BRP: 2, TSEG1: 10, TSEG2: 5, SJW: 4, BTR: C149h, CLK: 8MHz + BR: 250_000 bit/s, SP: 75.00%, BRP: 2, TSEG1: 11, TSEG2: 4, SJW: 4, BTR: C13Ah, CLK: 8MHz + BR: 250_000 bit/s, SP: 81.25%, BRP: 2, TSEG1: 12, TSEG2: 3, SJW: 3, BTR: 812Bh, CLK: 8MHz + BR: 250_000 bit/s, SP: 87.50%, BRP: 2, TSEG1: 13, TSEG2: 2, SJW: 2, BTR: 411Ch, CLK: 8MHz + BR: 250_000 bit/s, SP: 93.75%, BRP: 2, TSEG1: 14, TSEG2: 1, SJW: 1, BTR: 010Dh, CLK: 8MHz + + It is possible to specify CAN 2.0 bit timings using the config file: - .. code-block:: none [default] From 87d00d1803495c9824821440c6da75e26fa85f28 Mon Sep 17 00:00:00 2001 From: zariiii9003 <52598363+zariiii9003@users.noreply.github.com> Date: Sat, 28 Jan 2023 14:33:09 +0100 Subject: [PATCH 4/5] fix tests --- can/bit_timing.py | 4 ++-- test/test_bit_timing.py | 27 ++++++++++++++++++++++----- 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/can/bit_timing.py b/can/bit_timing.py index 989073ae9..4fada145b 100644 --- a/can/bit_timing.py +++ b/can/bit_timing.py @@ -1008,9 +1008,9 @@ def __str__(self) -> str: f"NTSEG1: {self.nom_tseg1}", f"NTSEG2: {self.nom_tseg2}", f"NSJW: {self.nom_sjw}", - f"DBR: {self.data_bitrate} bit/s", + f"DBR: {self.data_bitrate:_} bit/s", f"DSP: {self.data_sample_point:.2f}%", - f"DBRP: {self.data_brp:_}", + f"DBRP: {self.data_brp}", f"DTSEG1: {self.data_tseg1}", f"DTSEG2: {self.data_tseg2}", f"DSJW: {self.data_sjw}", diff --git a/test/test_bit_timing.py b/test/test_bit_timing.py index 669308f9d..a0d4e03a5 100644 --- a/test/test_bit_timing.py +++ b/test/test_bit_timing.py @@ -271,8 +271,8 @@ def test_equality(): def test_string_representation(): timing = can.BitTiming(f_clock=8_000_000, brp=1, tseg1=5, tseg2=2, sjw=1) assert str(timing) == ( - "BR 1000000 bit/s, SP: 75.00%, BRP: 1, TSEG1: 5, TSEG2: 2, SJW: 1, " - "BTR: 0014h, f_clock: 8MHz" + "BR: 1_000_000 bit/s, SP: 75.00%, BRP: 1, TSEG1: 5, TSEG2: 2, SJW: 1, " + "BTR: 0014h, CLK: 8MHz" ) fd_timing = can.BitTimingFd( @@ -287,9 +287,9 @@ def test_string_representation(): data_sjw=10, ) assert str(fd_timing) == ( - "NBR: 500000 bit/s, NSP: 75.00%, NBRP: 1, NTSEG1: 119, NTSEG2: 40, NSJW: 40, " - "DBR: 2000000 bit/s, DSP: 75.00%, DBRP: 1, DTSEG1: 29, DTSEG2: 10, DSJW: 10, " - "f_clock: 80MHz" + "NBR: 500_000 bit/s, NSP: 75.00%, NBRP: 1, NTSEG1: 119, NTSEG2: 40, NSJW: 40, " + "DBR: 2_000_000 bit/s, DSP: 75.00%, DBRP: 1, DTSEG1: 29, DTSEG2: 10, DSJW: 10, " + "CLK: 80MHz" ) @@ -316,6 +316,23 @@ def test_repr(): ) +def test_hash(): + _timings = { + can.BitTiming(f_clock=8_000_000, brp=1, tseg1=5, tseg2=2, sjw=1, nof_samples=1), + can.BitTimingFd( + f_clock=80_000_000, + nom_brp=1, + nom_tseg1=119, + nom_tseg2=40, + nom_sjw=40, + data_brp=1, + data_tseg1=29, + data_tseg2=10, + data_sjw=10, + ), + } + + def test_mapping(): timing = can.BitTiming(f_clock=8_000_000, brp=1, tseg1=5, tseg2=2, sjw=1) timing_dict = dict(timing) From e7cfb5d291e0deaa49b8e28557efcfb02a6585c9 Mon Sep 17 00:00:00 2001 From: zariiii9003 <52598363+zariiii9003@users.noreply.github.com> Date: Sat, 28 Jan 2023 15:28:30 +0100 Subject: [PATCH 5/5] rename variable --- doc/bit_timing.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/bit_timing.rst b/doc/bit_timing.rst index 7c272d270..73005a3c6 100644 --- a/doc/bit_timing.rst +++ b/doc/bit_timing.rst @@ -70,13 +70,13 @@ produce an overview of possible bit timings for your desired bit rate: >>> import can ... >>> timings = set() - >>> for sp in range(50, 100): + >>> for sample_point in range(50, 100): ... with contextlib.suppress(ValueError): ... timings.add( ... can.BitTiming.from_sample_point( ... f_clock=8_000_000, ... bitrate=250_000, - ... sample_point=sp, + ... sample_point=sample_point, ... ) ... ) ...