summaryrefslogtreecommitdiff
path: root/drivers/net/can
diff options
context:
space:
mode:
authorVincent Mailhol <mailhol@kernel.org>2025-11-26 11:16:15 +0100
committerMarc Kleine-Budde <mkl@pengutronix.de>2025-11-26 11:20:44 +0100
commitf5de373ae455f1db6cf15033d660ac0046bcb0ff (patch)
treeef57696ed928b1b7d61c2215981987ebee40cf73 /drivers/net/can
parenta6ddf91a4f9718cec712785904c57b7117f61d6c (diff)
can: calc_bittiming: add can_calc_sample_point_pwm()
The optimum sample point value depends on the bit symmetry. The more asymmetric the bit is, the more the sample point would be located towards the end of the bit. On the contrary, if the transceiver only has a small asymmetry, the optimal sample point would be slightly after the centre of the bit. For NRZ encoding (used by Classical CAN, CAN FD and CAN XL with TMS off), the optimum sample points values are above 70% as implemented in can_calc_sample_point_nrz(). When TMS is on, CAN XL optimum sample points are near to 50% or 60% [1]. Add can_calc_sample_point_pwm() which returns a sample point which is suitable for PWM encoding. We crafted the formula to make it return the same values as below table (source: table 3 of [1]). Bit rate (Mbits/s) Sample point ------------------------------------- 2.0 51.3% 5.0 53.1% 8.0 55.0% 10.0 56.3% 12.3 53.8% 13.3 58.3% 14.5 54.5% 16.0 60.0% 17.7 55.6% 20.0 62.5% The calculation simply consists of setting a slightly too high sample point and then letting can_update_sample_point() correct the values. For now, it is just a formula up our sleeves which matches the empirical observations of [1]. Once CiA recommendations become available, can_calc_sample_point_pwm() should be updated accordingly. [1] CAN XL system design: Clock tolerances and edge deviations edge deviations Link: https://www.can-cia.org/fileadmin/cia/documents/publications/cnlm/december_2024/cnlm_24-4_p18_can_xl_system_design_clock_tolerances_and_edge_deviations_dr_arthur_mutter_bosch.pdf Signed-off-by: Vincent Mailhol <mailhol@kernel.org> Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net> Link: https://patch.msgid.link/20251126-canxl-v8-14-e7e3eb74f889@pengutronix.de Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
Diffstat (limited to 'drivers/net/can')
-rw-r--r--drivers/net/can/dev/calc_bittiming.c18
1 files changed, 18 insertions, 0 deletions
diff --git a/drivers/net/can/dev/calc_bittiming.c b/drivers/net/can/dev/calc_bittiming.c
index bacdf3b218d3..60a505ce69de 100644
--- a/drivers/net/can/dev/calc_bittiming.c
+++ b/drivers/net/can/dev/calc_bittiming.c
@@ -22,6 +22,21 @@ static int can_calc_sample_point_nrz(const struct can_bittiming *bt)
return 875;
}
+/* Sample points for Pulse-Width Modulation encoding. */
+static int can_calc_sample_point_pwm(const struct can_bittiming *bt)
+{
+ if (bt->bitrate > 15 * MEGA /* BPS */)
+ return 625;
+
+ if (bt->bitrate > 9 * MEGA /* BPS */)
+ return 600;
+
+ if (bt->bitrate > 4 * MEGA /* BPS */)
+ return 560;
+
+ return 520;
+}
+
/* Bit-timing calculation derived from:
*
* Code based on LinCAN sources and H8S2638 project
@@ -93,6 +108,9 @@ int can_calc_bittiming(const struct net_device *dev, struct can_bittiming *bt,
if (bt->sample_point)
sample_point_reference = bt->sample_point;
+ else if (btc == priv->xl.data_bittiming_const &&
+ (priv->ctrlmode & CAN_CTRLMODE_XL_TMS))
+ sample_point_reference = can_calc_sample_point_pwm(bt);
else
sample_point_reference = can_calc_sample_point_nrz(bt);