From 2caa69919a2daaa0becef6a7480df4b88340a4ba Mon Sep 17 00:00:00 2001 From: Karl Fessel Date: Tue, 30 Sep 2025 21:37:22 +0200 Subject: [PATCH 1/2] sys/can: improve SJW calculation --- sys/can/device.c | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/sys/can/device.c b/sys/can/device.c index 7a654cc4e233..ecfd60912cc4 100644 --- a/sys/can/device.c +++ b/sys/can/device.c @@ -581,18 +581,25 @@ int can_device_calc_bittiming(uint32_t clock, const struct can_bittiming_const * timing->phase_seg1 = tseg1 - timing->prop_seg; timing->phase_seg2 = tseg2; - if (!timing->sjw || !timing_const->sjw_max) { - timing->sjw = SJW; - } - else { - if (timing->sjw > timing_const->sjw_max) { - timing->sjw = timing_const->sjw_max; + /* this paper http://www.oertel-halle.de/files/cia99paper.pdf might help to understand SJW */ + if (!timing->sjw) { + if (!timing_const->sjw_max) { + /* fallback if no device max value is known */ + timing->sjw = SJW; } - if (timing->sjw > tseg2) { - timing->sjw = tseg2; + else { + /* try to find the max_value start at max */ + timing->sjw = timing_const->sjw_max; } } - + if (timing->sjw > timing->phase_seg2) { + /* SJW shall not be bigger than phase segment 1 */ + timing->sjw = timing->phase_seg2; + } + if (timing->sjw > timing->phase_seg1) { + /* SJW shall not be bigger than phase segment 1 */ + timing->sjw = timing->phase_seg1; + } timing->brp = best_brp; timing->bitrate = clock / (timing->brp * (CAN_SYNC_SEG + tseg1 + tseg2)); From a40a44262535f8949772d9578a2e6326e2f6ee02 Mon Sep 17 00:00:00 2001 From: Karl Fessel Date: Wed, 1 Oct 2025 12:48:30 +0200 Subject: [PATCH 2/2] sys/can: bittiming calculation debug-result-print --- sys/can/device.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/sys/can/device.c b/sys/can/device.c index ecfd60912cc4..b6dd572c2d84 100644 --- a/sys/can/device.c +++ b/sys/can/device.c @@ -604,9 +604,10 @@ int can_device_calc_bittiming(uint32_t clock, const struct can_bittiming_const * timing->bitrate = clock / (timing->brp * (CAN_SYNC_SEG + tseg1 + tseg2)); - DEBUG("bitrate=%" PRIu32 ", sample_point=%" PRIu32 ", brp=%" PRIu32 ", prop_seg=%" PRIu32 - ", phase_seg1=%" PRIu32 ", phase_seg2=%" PRIu32 "\n", timing->bitrate, timing->sample_point, - timing->brp, timing->prop_seg, timing->phase_seg1, timing->phase_seg2); + DEBUG("clock=%" PRIu32 ", bitrate=%" PRIu32 ", sample_point=%" PRIu32 ", brp=%" PRIu32 + ", prop_seg=%" PRIu32", phase_seg1=%" PRIu32 ", phase_seg2=%" PRIu32", sjw=%" PRIu32 "\n", + clock, timing->bitrate, timing->sample_point, timing->brp, + timing->prop_seg, timing->phase_seg1, timing->phase_seg2, timing->sjw); return 0; }