@@ -213,17 +213,10 @@ def from_registers(
213213 )
214214
215215 @classmethod
216- def from_sample_point (
216+ def iterate_from_sample_point (
217217 cls , f_clock : int , bitrate : int , sample_point : float = 69.0
218- ) -> "BitTiming" :
219- """Create a :class:`~can.BitTiming` instance for a sample point.
220-
221- This function tries to find bit timings, which are close to the requested
222- sample point. It does not take physical bus properties into account, so the
223- calculated bus timings might not work properly for you.
224-
225- The :func:`oscillator_tolerance` function might be helpful to evaluate the
226- bus timings.
218+ ) -> Iterator ["BitTiming" ]:
219+ """Create a :class:`~can.BitTiming` iterator with all the solutions for a sample point.
227220
228221 :param int f_clock:
229222 The CAN system clock frequency in Hz.
@@ -238,7 +231,6 @@ def from_sample_point(
238231 if sample_point < 50.0 :
239232 raise ValueError (f"sample_point (={ sample_point } ) must not be below 50%." )
240233
241- possible_solutions : List [BitTiming ] = []
242234 for brp in range (1 , 65 ):
243235 nbt = round (int (f_clock / (bitrate * brp )))
244236 if nbt < 8 :
@@ -264,10 +256,40 @@ def from_sample_point(
264256 sjw = sjw ,
265257 strict = True ,
266258 )
267- possible_solutions . append ( bt )
259+ yield bt
268260 except ValueError :
269261 continue
270262
263+ @classmethod
264+ def from_sample_point (
265+ cls , f_clock : int , bitrate : int , sample_point : float = 69.0
266+ ) -> "BitTiming" :
267+ """Create a :class:`~can.BitTiming` instance for a sample point.
268+
269+ This function tries to find bit timings, which are close to the requested
270+ sample point. It does not take physical bus properties into account, so the
271+ calculated bus timings might not work properly for you.
272+
273+ The :func:`oscillator_tolerance` function might be helpful to evaluate the
274+ bus timings.
275+
276+ :param int f_clock:
277+ The CAN system clock frequency in Hz.
278+ :param int bitrate:
279+ Bitrate in bit/s.
280+ :param int sample_point:
281+ The sample point value in percent.
282+ :raises ValueError:
283+ if the arguments are invalid.
284+ """
285+
286+ if sample_point < 50.0 :
287+ raise ValueError (f"sample_point (={ sample_point } ) must not be below 50%." )
288+
289+ possible_solutions : List [BitTiming ] = list (
290+ cls .iterate_from_sample_point (f_clock , bitrate , sample_point )
291+ )
292+
271293 if not possible_solutions :
272294 raise ValueError ("No suitable bit timings found." )
273295
@@ -729,22 +751,15 @@ def from_bitrate_and_segments( # pylint: disable=too-many-arguments
729751 return bt
730752
731753 @classmethod
732- def from_sample_point (
754+ def iterate_from_sample_point (
733755 cls ,
734756 f_clock : int ,
735757 nom_bitrate : int ,
736758 nom_sample_point : float ,
737759 data_bitrate : int ,
738760 data_sample_point : float ,
739- ) -> "BitTimingFd" :
740- """Create a :class:`~can.BitTimingFd` instance for a given nominal/data sample point pair.
741-
742- This function tries to find bit timings, which are close to the requested
743- sample points. It does not take physical bus properties into account, so the
744- calculated bus timings might not work properly for you.
745-
746- The :func:`oscillator_tolerance` function might be helpful to evaluate the
747- bus timings.
761+ ) -> Iterator ["BitTimingFd" ]:
762+ """Create an :class:`~can.BitTimingFd` iterator with all the solutions for a sample point.
748763
749764 :param int f_clock:
750765 The CAN system clock frequency in Hz.
@@ -769,8 +784,6 @@ def from_sample_point(
769784 f"data_sample_point (={ data_sample_point } ) must not be below 50%."
770785 )
771786
772- possible_solutions : List [BitTimingFd ] = []
773-
774787 sync_seg = 1
775788
776789 for nom_brp in range (1 , 257 ):
@@ -818,10 +831,61 @@ def from_sample_point(
818831 data_sjw = data_sjw ,
819832 strict = True ,
820833 )
821- possible_solutions . append ( bt )
834+ yield bt
822835 except ValueError :
823836 continue
824837
838+ @classmethod
839+ def from_sample_point (
840+ cls ,
841+ f_clock : int ,
842+ nom_bitrate : int ,
843+ nom_sample_point : float ,
844+ data_bitrate : int ,
845+ data_sample_point : float ,
846+ ) -> "BitTimingFd" :
847+ """Create a :class:`~can.BitTimingFd` instance for a sample point.
848+
849+ This function tries to find bit timings, which are close to the requested
850+ sample points. It does not take physical bus properties into account, so the
851+ calculated bus timings might not work properly for you.
852+
853+ The :func:`oscillator_tolerance` function might be helpful to evaluate the
854+ bus timings.
855+
856+ :param int f_clock:
857+ The CAN system clock frequency in Hz.
858+ :param int nom_bitrate:
859+ Nominal bitrate in bit/s.
860+ :param int nom_sample_point:
861+ The sample point value of the arbitration phase in percent.
862+ :param int data_bitrate:
863+ Data bitrate in bit/s.
864+ :param int data_sample_point:
865+ The sample point value of the data phase in percent.
866+ :raises ValueError:
867+ if the arguments are invalid.
868+ """
869+ if nom_sample_point < 50.0 :
870+ raise ValueError (
871+ f"nom_sample_point (={ nom_sample_point } ) must not be below 50%."
872+ )
873+
874+ if data_sample_point < 50.0 :
875+ raise ValueError (
876+ f"data_sample_point (={ data_sample_point } ) must not be below 50%."
877+ )
878+
879+ possible_solutions : List [BitTimingFd ] = list (
880+ cls .iterate_from_sample_point (
881+ f_clock ,
882+ nom_bitrate ,
883+ nom_sample_point ,
884+ data_bitrate ,
885+ data_sample_point ,
886+ )
887+ )
888+
825889 if not possible_solutions :
826890 raise ValueError ("No suitable bit timings found." )
827891
0 commit comments