@@ -36,6 +36,7 @@ def __init__(
36
36
tseg2 : int ,
37
37
sjw : int ,
38
38
nof_samples : int = 1 ,
39
+ strict : bool = False ,
39
40
) -> None :
40
41
"""
41
42
:param int f_clock:
@@ -56,6 +57,10 @@ def __init__(
56
57
In this case, the bit will be sampled three quanta in a row,
57
58
with the last sample being taken in the edge between TSEG1 and TSEG2.
58
59
Three samples should only be used for relatively slow baudrates.
60
+ :param strict:
61
+ If True, restrict bit timings to the minimum required range as defined in
62
+ ISO 11898. This can be used to ensure compatibility across a wide variety
63
+ of CAN hardware.
59
64
:raises ValueError:
60
65
if the arguments are invalid.
61
66
"""
@@ -68,19 +73,13 @@ def __init__(
68
73
"nof_samples" : nof_samples ,
69
74
}
70
75
self ._validate ()
76
+ if strict :
77
+ self ._restrict_to_minimum_range ()
71
78
72
79
def _validate (self ) -> None :
73
- if not 8 <= self .nbt <= 25 :
74
- raise ValueError (f"nominal bit time (={ self .nbt } ) must be in [8...25]." )
75
-
76
80
if not 1 <= self .brp <= 64 :
77
81
raise ValueError (f"bitrate prescaler (={ self .brp } ) must be in [1...64]." )
78
82
79
- if not 5_000 <= self .bitrate <= 2_000_000 :
80
- raise ValueError (
81
- f"bitrate (={ self .bitrate } ) must be in [5,000...2,000,000]."
82
- )
83
-
84
83
if not 1 <= self .tseg1 <= 16 :
85
84
raise ValueError (f"tseg1 (={ self .tseg1 } ) must be in [1...16]." )
86
85
@@ -104,6 +103,18 @@ def _validate(self) -> None:
104
103
if self .nof_samples not in (1 , 3 ):
105
104
raise ValueError ("nof_samples must be 1 or 3" )
106
105
106
+ def _restrict_to_minimum_range (self ) -> None :
107
+ if not 8 <= self .nbt <= 25 :
108
+ raise ValueError (f"nominal bit time (={ self .nbt } ) must be in [8...25]." )
109
+
110
+ if not 1 <= self .brp <= 32 :
111
+ raise ValueError (f"bitrate prescaler (={ self .brp } ) must be in [1...32]." )
112
+
113
+ if not 5_000 <= self .bitrate <= 1_000_000 :
114
+ raise ValueError (
115
+ f"bitrate (={ self .bitrate } ) must be in [5,000...1,000,000]."
116
+ )
117
+
107
118
@classmethod
108
119
def from_bitrate_and_segments (
109
120
cls ,
@@ -175,6 +186,11 @@ def from_registers(
175
186
:raises ValueError:
176
187
if the arguments are invalid.
177
188
"""
189
+ if not 0 <= btr0 < 2 ** 16 :
190
+ raise ValueError (f"Invalid btr0 value. ({ btr0 } )" )
191
+ if not 0 <= btr1 < 2 ** 16 :
192
+ raise ValueError (f"Invalid btr1 value. ({ btr1 } )" )
193
+
178
194
brp = (btr0 & 0x3F ) + 1
179
195
sjw = (btr0 >> 6 ) + 1
180
196
tseg1 = (btr1 & 0xF ) + 1
@@ -239,6 +255,7 @@ def from_sample_point(
239
255
tseg1 = tseg1 ,
240
256
tseg2 = tseg2 ,
241
257
sjw = sjw ,
258
+ strict = True ,
242
259
)
243
260
possible_solutions .append (bt )
244
261
except ValueError :
@@ -316,12 +333,12 @@ def sample_point(self) -> float:
316
333
317
334
@property
318
335
def btr0 (self ) -> int :
319
- """Bit timing register 0."""
336
+ """Bit timing register 0 for SJA1000 ."""
320
337
return (self .sjw - 1 ) << 6 | self .brp - 1
321
338
322
339
@property
323
340
def btr1 (self ) -> int :
324
- """Bit timing register 1."""
341
+ """Bit timing register 1 for SJA1000 ."""
325
342
sam = 1 if self .nof_samples == 3 else 0
326
343
return sam << 7 | (self .tseg2 - 1 ) << 4 | self .tseg1 - 1
327
344
0 commit comments