@@ -145,24 +145,29 @@ def from_sample_point(
145
145
for brp in range (1 , 65 ):
146
146
nbt = round (int (f_clock / (bitrate * brp )))
147
147
if nbt < 8 :
148
+ break
149
+
150
+ actual_bitrate = f_clock / (nbt * brp )
151
+ if abs (actual_bitrate - bitrate ) > bitrate / 256 :
148
152
continue
149
153
150
154
tseg1 = int (round (sample_point / 100 * nbt )) - 1
151
155
tseg2 = nbt - tseg1 - 1
152
156
153
- for sjw in range (1 , 5 ):
154
- try :
155
- bt = BitTiming (
156
- f_clock = f_clock ,
157
- bitrate = bitrate ,
158
- tseg1 = tseg1 ,
159
- tseg2 = tseg2 ,
160
- sjw = sjw ,
161
- )
162
- if abs (bt .sample_point - sample_point ) < 1 :
163
- possible_solutions .append (bt )
164
- except ValueError :
165
- continue
157
+ sjw = min (tseg2 , 4 )
158
+
159
+ try :
160
+ bt = BitTiming (
161
+ f_clock = f_clock ,
162
+ bitrate = bitrate ,
163
+ tseg1 = tseg1 ,
164
+ tseg2 = tseg2 ,
165
+ sjw = sjw ,
166
+ )
167
+ if abs (bt .sample_point - sample_point ) < 1 :
168
+ possible_solutions .append (bt )
169
+ except ValueError :
170
+ continue
166
171
167
172
if not possible_solutions :
168
173
raise ValueError ("No suitable bit timings found." )
@@ -229,8 +234,8 @@ def sample_point(self) -> float:
229
234
def oscillator_tolerance (self ) -> float :
230
235
"""Oscillator tolerance in percent."""
231
236
df_clock_list = [
232
- _oscillator_tolerance_criterion_1 (nom_sjw = self .sjw , nbt = self .nbt ),
233
- _oscillator_tolerance_criterion_2 (nbt = self .nbt , nom_tseg2 = self .tseg2 ),
237
+ _oscillator_tolerance_condition_1 (nom_sjw = self .sjw , nbt = self .nbt ),
238
+ _oscillator_tolerance_condition_2 (nbt = self .nbt , nom_tseg2 = self .tseg2 ),
234
239
]
235
240
return min (df_clock_list ) * 100
236
241
@@ -423,48 +428,55 @@ def from_sample_point(
423
428
424
429
possible_solutions : List [BitTimingFd ] = []
425
430
426
- def _generate_bit_timings () -> Iterator [BitTimingFdDict ]:
427
- for nom_brp in range (1 , 257 ):
428
- nbt = round (int (f_clock / (nom_bitrate * nom_brp )))
429
- if nbt < 8 :
430
- continue
431
+ for nom_brp in range (1 , 257 ):
432
+ nbt = round (int (f_clock / (nom_bitrate * nom_brp )))
433
+ if nbt < 8 :
434
+ break
431
435
432
- nom_tseg1 = int (round (nom_sample_point / 100 * nbt )) - 1
433
- nom_tseg2 = nbt - nom_tseg1 - 1
434
-
435
- for nom_sjw in range (1 , 129 ):
436
- for data_brp in range (1 , 257 ):
437
- dbt = round (int (f_clock / (data_bitrate * data_brp )))
438
- if dbt < 8 :
439
- continue
440
-
441
- data_tseg1 = int (round (data_sample_point / 100 * dbt )) - 1
442
- data_tseg2 = dbt - data_tseg1 - 1
443
-
444
- for data_sjw in range (1 , 17 ):
445
- yield {
446
- "f_clock" : f_clock ,
447
- "nom_bitrate" : nom_bitrate ,
448
- "nom_tseg1" : nom_tseg1 ,
449
- "nom_tseg2" : nom_tseg2 ,
450
- "nom_sjw" : nom_sjw ,
451
- "data_bitrate" : data_bitrate ,
452
- "data_tseg1" : data_tseg1 ,
453
- "data_tseg2" : data_tseg2 ,
454
- "data_sjw" : data_sjw ,
455
- }
456
-
457
- for bit_timings in _generate_bit_timings ():
458
- try :
459
- bt = BitTimingFd (** bit_timings )
460
- if (
461
- abs (bt .nom_sample_point - nom_sample_point ) < 1
462
- and abs (bt .data_sample_point - bt .data_sample_point ) < 1
463
- ):
464
- possible_solutions .append (bt )
465
- except ValueError :
436
+ actual_nom_bitrate = f_clock / (nbt * nom_brp )
437
+ if abs (actual_nom_bitrate - nom_bitrate ) > nom_bitrate / 256 :
466
438
continue
467
439
440
+ nom_tseg1 = int (round (nom_sample_point / 100 * nbt )) - 1
441
+ nom_tseg2 = nbt - nom_tseg1 - 1
442
+
443
+ nom_sjw = min (nom_tseg2 , 128 )
444
+
445
+ for data_brp in range (1 , 257 ):
446
+ dbt = round (int (f_clock / (data_bitrate * data_brp )))
447
+ if dbt < 8 :
448
+ break
449
+
450
+ actual_data_bitrate = f_clock / (dbt * data_brp )
451
+ if abs (actual_data_bitrate - data_bitrate ) > data_bitrate / 256 :
452
+ continue
453
+
454
+ data_tseg1 = int (round (data_sample_point / 100 * dbt )) - 1
455
+ data_tseg2 = dbt - data_tseg1 - 1
456
+
457
+ data_sjw = min (data_tseg2 , 16 )
458
+
459
+ bit_timings = {
460
+ "f_clock" : f_clock ,
461
+ "nom_bitrate" : nom_bitrate ,
462
+ "nom_tseg1" : nom_tseg1 ,
463
+ "nom_tseg2" : nom_tseg2 ,
464
+ "nom_sjw" : nom_sjw ,
465
+ "data_bitrate" : data_bitrate ,
466
+ "data_tseg1" : data_tseg1 ,
467
+ "data_tseg2" : data_tseg2 ,
468
+ "data_sjw" : data_sjw ,
469
+ }
470
+ try :
471
+ bt = BitTimingFd (** bit_timings )
472
+ if (
473
+ abs (bt .nom_sample_point - nom_sample_point ) < 1
474
+ and abs (bt .data_sample_point - bt .data_sample_point ) < 1
475
+ ):
476
+ possible_solutions .append (bt )
477
+ except ValueError :
478
+ continue
479
+
468
480
if not possible_solutions :
469
481
raise ValueError ("No suitable bit timings found." )
470
482
@@ -479,8 +491,6 @@ def _generate_bit_timings() -> Iterator[BitTimingFdDict]:
479
491
for key , reverse in (
480
492
(lambda x : x .data_brp , False ),
481
493
(lambda x : x .nom_brp , False ),
482
- (lambda x : x .data_sjw , True ),
483
- (lambda x : x .nom_sjw , True ),
484
494
(lambda x : x .oscillator_tolerance , True ),
485
495
):
486
496
possible_solutions .sort (key = key , reverse = reverse )
@@ -555,16 +565,16 @@ def f_clock(self) -> int:
555
565
def oscillator_tolerance (self ) -> float :
556
566
"""Oscillator tolerance in percent."""
557
567
df_clock_list = [
558
- _oscillator_tolerance_criterion_1 (nom_sjw = self .nom_sjw , nbt = self .nbt ),
559
- _oscillator_tolerance_criterion_2 (nbt = self .nbt , nom_tseg2 = self .nom_tseg2 ),
560
- _oscillator_tolerance_criterion_3 (data_sjw = self .data_sjw , dbt = self .dbt ),
561
- _oscillator_tolerance_criterion_4 (
568
+ _oscillator_tolerance_condition_1 (nom_sjw = self .nom_sjw , nbt = self .nbt ),
569
+ _oscillator_tolerance_condition_2 (nbt = self .nbt , nom_tseg2 = self .nom_tseg2 ),
570
+ _oscillator_tolerance_condition_3 (data_sjw = self .data_sjw , dbt = self .dbt ),
571
+ _oscillator_tolerance_condition_4 (
562
572
data_tseg2 = self .data_tseg2 ,
563
573
nbt = self .nbt ,
564
574
data_brp = self .data_brp ,
565
575
nom_brp = self .nom_brp ,
566
576
),
567
- _oscillator_tolerance_criterion_5 (
577
+ _oscillator_tolerance_condition_5 (
568
578
data_sjw = self .data_sjw ,
569
579
data_brp = self .data_brp ,
570
580
nom_brp = self .nom_brp ,
@@ -650,25 +660,29 @@ def __iter__(self) -> Iterator[str]:
650
660
return self ._data .__iter__ ()
651
661
652
662
653
- def _oscillator_tolerance_criterion_1 (nom_sjw : int , nbt : int ) -> float :
654
- return nom_sjw / (20 * nbt )
663
+ def _oscillator_tolerance_condition_1 (nom_sjw : int , nbt : int ) -> float :
664
+ """Arbitration phase - resynchronization"""
665
+ return nom_sjw / (2 * 10 * nbt )
655
666
656
667
657
- def _oscillator_tolerance_criterion_2 (nbt : int , nom_tseg2 : int ) -> float :
668
+ def _oscillator_tolerance_condition_2 (nbt : int , nom_tseg2 : int ) -> float :
669
+ """Arbitration phase - sampling of bit after error flag"""
658
670
return nom_tseg2 / (2 * (13 * nbt - nom_tseg2 ))
659
671
660
672
661
- def _oscillator_tolerance_criterion_3 (data_sjw : int , dbt : int ) -> float :
662
- return data_sjw / (20 * dbt )
673
+ def _oscillator_tolerance_condition_3 (data_sjw : int , dbt : int ) -> float :
674
+ """Data phase - resynchronization"""
675
+ return data_sjw / (2 * 10 * dbt )
663
676
664
677
665
- def _oscillator_tolerance_criterion_4 (
678
+ def _oscillator_tolerance_condition_4 (
666
679
data_tseg2 : int , nbt : int , data_brp : int , nom_brp : int
667
680
) -> float :
668
- return data_tseg2 / (2 * ((2 * nbt - data_tseg2 ) * data_brp / nom_brp + 7 * nbt ))
681
+ """Data phase - sampling of bit after error flag"""
682
+ return data_tseg2 / (2 * ((6 * nbt - data_tseg2 ) * data_brp / nom_brp + 7 * nbt ))
669
683
670
684
671
- def _oscillator_tolerance_criterion_5 (
685
+ def _oscillator_tolerance_condition_5 (
672
686
data_sjw : int ,
673
687
data_brp : int ,
674
688
nom_brp : int ,
@@ -677,6 +691,9 @@ def _oscillator_tolerance_criterion_5(
677
691
nbt : int ,
678
692
dbt : int ,
679
693
) -> float :
680
- return (data_sjw - (nom_brp / data_brp - 1 )) / (
681
- 2 * ((2 * nbt - nom_tseg2 ) * nom_brp / data_brp + data_tseg2 + 4 * dbt )
694
+ """Data phase - bit rate switch"""
695
+ max_correctable_phase_shift = data_sjw - max (0.0 , nom_brp / data_brp - 1 )
696
+ time_between_resync = 2 * (
697
+ (2 * nbt - nom_tseg2 ) * nom_brp / data_brp + data_tseg2 + 4 * dbt
682
698
)
699
+ return max_correctable_phase_shift / time_between_resync
0 commit comments