From 9f8cc8fb6919072ab3b4cea199723cbab334ff88 Mon Sep 17 00:00:00 2001 From: Ashcon Mohseninia Date: Mon, 7 Jul 2025 10:34:22 +0100 Subject: [PATCH 1/6] Allow for fractional baudrates --- mcan/src/config.rs | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/mcan/src/config.rs b/mcan/src/config.rs index bc0c389..66bba0e 100644 --- a/mcan/src/config.rs +++ b/mcan/src/config.rs @@ -199,19 +199,23 @@ impl BitTiming { let f_out = self.bitrate; let bit_time_quanta = self.time_quanta_per_bit(); let f_q = f_out * bit_time_quanta; - if let Some(0) = f_can.to_Hz().checked_rem(f_q.to_Hz()) { - let prescaler = f_can / f_q; - if !valid.prescaler.contains(&prescaler) { - Err(BitTimingError::PrescalerOutOfRange(valid.prescaler.clone())) - } else { - Ok(prescaler as u16) + let max_tolerance = self.bitrate.to_Hz() / 2000; // 0.05% tolerance + match f_can.to_Hz().checked_rem(f_q.to_Hz()) { + Some(x) if x <= max_tolerance => { + let prescaler = f_can / f_q; + if !valid.prescaler.contains(&prescaler) { + Err(BitTimingError::PrescalerOutOfRange(valid.prescaler.clone())) + } else { + Ok(prescaler as u16) + } + } + _ => { + Err(BitTimingError::NoValidPrescaler { + can_clock: f_can, + bitrate: f_out, + bit_time_quanta, + }) } - } else { - Err(BitTimingError::NoValidPrescaler { - can_clock: f_can, - bitrate: f_out, - bit_time_quanta, - }) } } } From 6e67323b5aadf8a7b5dc3402683bf4b40426f30c Mon Sep 17 00:00:00 2001 From: Ashcon Mohseninia Date: Mon, 7 Jul 2025 10:35:10 +0100 Subject: [PATCH 2/6] Cargo fmt --- mcan/src/config.rs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/mcan/src/config.rs b/mcan/src/config.rs index 66bba0e..241df39 100644 --- a/mcan/src/config.rs +++ b/mcan/src/config.rs @@ -209,13 +209,11 @@ impl BitTiming { Ok(prescaler as u16) } } - _ => { - Err(BitTimingError::NoValidPrescaler { - can_clock: f_can, - bitrate: f_out, - bit_time_quanta, - }) - } + _ => Err(BitTimingError::NoValidPrescaler { + can_clock: f_can, + bitrate: f_out, + bit_time_quanta, + }), } } } From 16fa92f7f65ce0f43fcc4fce766877b3caddf15b Mon Sep 17 00:00:00 2001 From: Ashcon Mohseninia Date: Tue, 9 Sep 2025 07:50:31 +0100 Subject: [PATCH 3/6] Allow configuration for fractional bitrates --- mcan/src/config.rs | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/mcan/src/config.rs b/mcan/src/config.rs index 241df39..58abe5e 100644 --- a/mcan/src/config.rs +++ b/mcan/src/config.rs @@ -68,14 +68,22 @@ pub struct BitTiming { /// MCAN peripheral is divisible into time quanta such that the bit time /// determined by `phase_seg_1` and `phase_seg_2` is a whole number of time /// quanta. + /// + /// When [`allow_fractional`] is selected, the real bitrate + /// is allowed to be up to 0.05% off (Which is within tolerance) pub bitrate: HertzU32, + /// Allows for fractional bitrates where there may be no perfect + /// combination of bit-timing parameters. This is useful for bitrates + /// like 83.3kbps where some tolerance is allowed (Up to 0.05%). + pub allow_fractional: bool } impl BitTiming { /// Create an instance /// /// Nominal bitrate value must be provided, all other settings come - /// pre-populated with default values. + /// pre-populated with default values. No fractional bitrates + /// are allowed. pub fn new(bitrate: HertzU32) -> Self { Self { // Note: SWJ and {N,D}TSEG{1,2} defaults come from reset values @@ -83,6 +91,7 @@ impl BitTiming { phase_seg_1: 0xB, phase_seg_2: 0x4, bitrate, + allow_fractional: false } } } @@ -199,7 +208,11 @@ impl BitTiming { let f_out = self.bitrate; let bit_time_quanta = self.time_quanta_per_bit(); let f_q = f_out * bit_time_quanta; - let max_tolerance = self.bitrate.to_Hz() / 2000; // 0.05% tolerance + let max_tolerance = if self.allow_fractional { + self.bitrate.to_Hz() / 2000 // 0.05% tolerance + } else { + 0 + }; match f_can.to_Hz().checked_rem(f_q.to_Hz()) { Some(x) if x <= max_tolerance => { let prescaler = f_can / f_q; From 1ed91e38957dd304aca058f79414f20eeceb00c0 Mon Sep 17 00:00:00 2001 From: Ashcon Mohseninia Date: Wed, 10 Sep 2025 07:32:05 +0100 Subject: [PATCH 4/6] Rustfmt --- mcan/src/config.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mcan/src/config.rs b/mcan/src/config.rs index 58abe5e..a8641e2 100644 --- a/mcan/src/config.rs +++ b/mcan/src/config.rs @@ -68,14 +68,14 @@ pub struct BitTiming { /// MCAN peripheral is divisible into time quanta such that the bit time /// determined by `phase_seg_1` and `phase_seg_2` is a whole number of time /// quanta. - /// + /// /// When [`allow_fractional`] is selected, the real bitrate /// is allowed to be up to 0.05% off (Which is within tolerance) pub bitrate: HertzU32, /// Allows for fractional bitrates where there may be no perfect /// combination of bit-timing parameters. This is useful for bitrates /// like 83.3kbps where some tolerance is allowed (Up to 0.05%). - pub allow_fractional: bool + pub allow_fractional: bool, } impl BitTiming { @@ -91,7 +91,7 @@ impl BitTiming { phase_seg_1: 0xB, phase_seg_2: 0x4, bitrate, - allow_fractional: false + allow_fractional: false, } } } From a14f1ee3691b4bf835e180758b38bd99d7e15e8f Mon Sep 17 00:00:00 2001 From: Ashcon Mohseninia Date: Wed, 10 Sep 2025 10:32:39 +0100 Subject: [PATCH 5/6] Fix doc --- mcan/src/config.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mcan/src/config.rs b/mcan/src/config.rs index a8641e2..a296deb 100644 --- a/mcan/src/config.rs +++ b/mcan/src/config.rs @@ -69,7 +69,7 @@ pub struct BitTiming { /// determined by `phase_seg_1` and `phase_seg_2` is a whole number of time /// quanta. /// - /// When [`allow_fractional`] is selected, the real bitrate + /// When [`Self::allow_fractional`] is selected, the real bitrate /// is allowed to be up to 0.05% off (Which is within tolerance) pub bitrate: HertzU32, /// Allows for fractional bitrates where there may be no perfect From bab4ee260d839b49ea1034571e5f97da7a2ea6b7 Mon Sep 17 00:00:00 2001 From: Ashcon Mohseninia Date: Thu, 11 Sep 2025 12:33:36 +0100 Subject: [PATCH 6/6] Update changelog --- mcan/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/mcan/CHANGELOG.md b/mcan/CHANGELOG.md index 3875446..a073e12 100644 --- a/mcan/CHANGELOG.md +++ b/mcan/CHANGELOG.md @@ -3,6 +3,7 @@ Tagging in git follows a pattern: `mcan/`. ## [Unreleased] +- Added support for fractional baudrates (#59) ## [0.7.0] - 2025-04-23