From 258ea5a9ba504344d6fc0c80e6032e0a2d3d8fa3 Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Tue, 4 Jun 2019 10:02:10 +0200 Subject: [PATCH 01/15] can-calc-bit-timing: fix whitespace Signed-off-by: Marc Kleine-Budde --- can-calc-bit-timing.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/can-calc-bit-timing.c b/can-calc-bit-timing.c index 82fdda8..131f705 100644 --- a/can-calc-bit-timing.c +++ b/can-calc-bit-timing.c @@ -57,7 +57,7 @@ enum { __abs_choose_expr(x, char, \ __builtin_choose_expr( \ __builtin_types_compatible_p(typeof(x), char), \ - (char)({ signed char __x = (x); __x<0?-__x:__x; }), \ + (char)({ signed char __x = (x); __x < 0 ? -__x:__x; }), \ ((void)0))))))) #define __abs_choose_expr(x, type, other) __builtin_choose_expr( \ @@ -93,13 +93,13 @@ enum { */ #define clamp(val, lo, hi) min((typeof(val))max(val, lo), hi) -# define do_div(n,base) ({ \ +#define do_div(n, base) ({ \ uint32_t __base = (base); \ uint32_t __rem; \ __rem = ((uint64_t)(n)) % __base; \ (n) = ((uint64_t)(n)) / __base; \ __rem; \ - }) +}) /* */ From 9b639299747342a39b3fad2c67bccc103e0c248c Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Mon, 3 Jun 2019 19:50:11 +0200 Subject: [PATCH 02/15] can-calc-bit-timing: mark several structs and members as const Signed-off-by: Marc Kleine-Budde --- can-calc-bit-timing.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/can-calc-bit-timing.c b/can-calc-bit-timing.c index 131f705..f0366d1 100644 --- a/can-calc-bit-timing.c +++ b/can-calc-bit-timing.c @@ -115,14 +115,14 @@ typedef __u32 u32; struct calc_ref_clk { __u32 clk; /* CAN system clock frequency in Hz */ - char *name; + const char *name; }; struct calc_bittiming_const { - struct can_bittiming_const bittiming_const; + const struct can_bittiming_const bittiming_const; const struct calc_ref_clk ref_clk[16]; - void (*printf_btr)(struct can_bittiming *bt, bool hdr); + const void (*printf_btr)(struct can_bittiming *bt, bool hdr); }; /* @@ -324,7 +324,7 @@ static void printf_btr_mcan(struct can_bittiming *bt, bool hdr) } } -static struct calc_bittiming_const can_calc_consts[] = { +static const struct calc_bittiming_const can_calc_consts[] = { { .bittiming_const = { .name = "sja1000", @@ -519,7 +519,7 @@ static struct calc_bittiming_const can_calc_consts[] = { }, }; -static long common_bitrates[] = { +static const unsigned int common_bitrates[] = { 1000000, 800000, 500000, From 927f70e588446fa4ce35f049b8bc232183d9e5d2 Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Fri, 29 Apr 2016 16:24:58 +0200 Subject: [PATCH 03/15] can-calc-bit-timing: rename spt -> sample_point Signed-off-by: Marc Kleine-Budde --- can-calc-bit-timing.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/can-calc-bit-timing.c b/can-calc-bit-timing.c index f0366d1..de6f73b 100644 --- a/can-calc-bit-timing.c +++ b/can-calc-bit-timing.c @@ -749,7 +749,7 @@ static void print_bit_timing(const struct calc_bittiming_const *btc, const struct can_bittiming *ref_bt, const struct calc_ref_clk *ref_clk, unsigned int bitrate_nominal, - unsigned int spt_nominal, + unsigned int sample_point_nominal, bool quiet) { struct net_device dev = { @@ -757,9 +757,9 @@ static void print_bit_timing(const struct calc_bittiming_const *btc, }; struct can_bittiming bt = { .bitrate = bitrate_nominal, - .sample_point = spt_nominal, + .sample_point = sample_point_nominal, }; - long rate_error, spt_error; + unsigned int rate_error, sample_point_error; if (!quiet) { printf("Bit timing parameters for %s%s%s%s with %.6f MHz ref clock\n" @@ -791,11 +791,11 @@ static void print_bit_timing(const struct calc_bittiming_const *btc, } /* get nominal sample point */ - if (!spt_nominal) - spt_nominal = get_cia_sample_point(bitrate_nominal); + if (!sample_point_nominal) + sample_point_nominal = get_cia_sample_point(bitrate_nominal); rate_error = abs(bitrate_nominal - bt.bitrate); - spt_error = abs(spt_nominal - bt.sample_point); + sample_point_error = abs(sample_point_nominal - bt.sample_point); printf("%7d " /* Bitrate */ "%6d %3d %4d %4d " /* TQ[ns], PrS, PhS1, PhS2 */ @@ -812,15 +812,15 @@ static void print_bit_timing(const struct calc_bittiming_const *btc, printf("%4.1f%% ", 100.0 * rate_error / bitrate_nominal); - printf("%4.1f%% %4.1f%% ", /* nom SampP, real SampP */ - spt_nominal / 10.0, + printf("%4.1f%% %4.1f%% ", /* nom Sample Point, real Sample Point */ + sample_point_nominal / 10.0, bt.sample_point / 10.0); - if (100.0 * spt_error / spt_nominal > 99.9) + if (100.0 * sample_point_error / sample_point_nominal > 99.9) printf("≥100%% "); else - printf("%4.1f%% ", /* SampP Error */ - 100.0 * spt_error / spt_nominal); + printf("%4.1f%% ", /* Sample Point Error */ + 100.0 * sample_point_error / sample_point_nominal); if (btc->printf_btr) btc->printf_btr(&bt, false); From 7bc81678bbdab23b039b693fec258b81a03b7e12 Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Fri, 29 Apr 2016 16:24:58 +0200 Subject: [PATCH 04/15] can-calc-bit-timing: rename rate -> bitrate Signed-off-by: Marc Kleine-Budde --- can-calc-bit-timing.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/can-calc-bit-timing.c b/can-calc-bit-timing.c index de6f73b..d1fb160 100644 --- a/can-calc-bit-timing.c +++ b/can-calc-bit-timing.c @@ -759,7 +759,7 @@ static void print_bit_timing(const struct calc_bittiming_const *btc, .bitrate = bitrate_nominal, .sample_point = sample_point_nominal, }; - unsigned int rate_error, sample_point_error; + unsigned int bitrate_error, sample_point_error; if (!quiet) { printf("Bit timing parameters for %s%s%s%s with %.6f MHz ref clock\n" @@ -794,7 +794,7 @@ static void print_bit_timing(const struct calc_bittiming_const *btc, if (!sample_point_nominal) sample_point_nominal = get_cia_sample_point(bitrate_nominal); - rate_error = abs(bitrate_nominal - bt.bitrate); + bitrate_error = abs(bitrate_nominal - bt.bitrate); sample_point_error = abs(sample_point_nominal - bt.sample_point); printf("%7d " /* Bitrate */ @@ -806,11 +806,11 @@ static void print_bit_timing(const struct calc_bittiming_const *btc, bt.sjw, bt.brp, bt.bitrate); - if (100.0 * rate_error / bitrate_nominal > 99.9) + if (100.0 * bitrate_error / bitrate_nominal > 99.9) printf("≥100%% "); else printf("%4.1f%% ", - 100.0 * rate_error / bitrate_nominal); + 100.0 * bitrate_error / bitrate_nominal); printf("%4.1f%% %4.1f%% ", /* nom Sample Point, real Sample Point */ sample_point_nominal / 10.0, From 7ec433f6a639ddc7fc44dc116d2a2cb2ca092763 Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Tue, 4 Jun 2019 10:55:30 +0200 Subject: [PATCH 05/15] can-calc-bit-timing: prepare for different can_bittiming (i.e. CAN-FD) Signed-off-by: Marc Kleine-Budde --- can-calc-bit-timing.c | 199 +++++++++++++++++++++++++----------------- 1 file changed, 121 insertions(+), 78 deletions(-) diff --git a/can-calc-bit-timing.c b/can-calc-bit-timing.c index d1fb160..3f4057f 100644 --- a/can-calc-bit-timing.c +++ b/can-calc-bit-timing.c @@ -2,7 +2,7 @@ /* can-calc-bit-timing.c: Calculate CAN bit timing parameters * * Copyright (C) 2008 Wolfgang Grandegger - * Copyright (C) 2016, 2021 Marc Kleine-Budde + * Copyright (C) 2016, 2021, 2022 Marc Kleine-Budde * * Derived from: * can_baud.c - CAN baudrate calculation @@ -122,9 +122,27 @@ struct calc_bittiming_const { const struct can_bittiming_const bittiming_const; const struct calc_ref_clk ref_clk[16]; + const void (*printf_btr)(struct can_bittiming *bt, bool hdr); }; +struct calc_data { + const struct can_bittiming_const *bittiming_const; + const void (*printf_btr)(struct can_bittiming *bt, bool hdr); + const char *name; + + const struct calc_ref_clk *ref_clks; + const unsigned int *bitrates; + + unsigned int sample_point; + + const struct calc_ref_clk *opt_ref_clk; + const unsigned int *opt_bitrates; + const struct can_bittiming *opt_bt; + + bool quiet; +}; + /* * minimal structs, just enough to be source level compatible */ @@ -529,6 +547,7 @@ static const unsigned int common_bitrates[] = { 50000, 20000, 10000, + 0 }; #define CAN_CALC_MAX_ERROR 50 /* in one-tenth of a percent */ @@ -745,12 +764,13 @@ static __u32 get_cia_sample_point(__u32 bitrate) return sampl_pt; } -static void print_bit_timing(const struct calc_bittiming_const *btc, - const struct can_bittiming *ref_bt, - const struct calc_ref_clk *ref_clk, - unsigned int bitrate_nominal, - unsigned int sample_point_nominal, - bool quiet) +static void print_bittiming_one(const struct can_bittiming_const *bittiming_const, + const struct can_bittiming *ref_bt, + const struct calc_ref_clk *ref_clk, + unsigned int bitrate_nominal, + unsigned int sample_point_nominal, + void (*printf_btr)(struct can_bittiming *bt, bool hdr), + bool quiet) { struct net_device dev = { .priv.clock.freq = ref_clk->clk, @@ -765,35 +785,31 @@ static void print_bit_timing(const struct calc_bittiming_const *btc, printf("Bit timing parameters for %s%s%s%s with %.6f MHz ref clock\n" "nominal real Bitrt nom real SampP\n" "Bitrate TQ[ns] PrS PhS1 PhS2 SJW BRP Bitrate Error SampP SampP Error ", - btc->bittiming_const.name, + bittiming_const->name, ref_clk->name ? " (" : "", ref_clk->name ? ref_clk->name : "", ref_clk->name ? ")" : "", ref_clk->clk / 1000000.0); - if (btc->printf_btr) - btc->printf_btr(&bt, true); + if (printf_btr) + printf_btr(&bt, true); printf("\n"); } if (ref_bt) { bt = *ref_bt; - if (can_fixup_bittiming(&dev, &bt, &btc->bittiming_const)) { + if (can_fixup_bittiming(&dev, &bt, bittiming_const)) { printf("%7d ***parameters exceed controller's range***\n", bitrate_nominal); return; } } else { - if (can_calc_bittiming(&dev, &bt, &btc->bittiming_const)) { + if (can_calc_bittiming(&dev, &bt, bittiming_const)) { printf("%7d ***bitrate not possible***\n", bitrate_nominal); return; } } - /* get nominal sample point */ - if (!sample_point_nominal) - sample_point_nominal = get_cia_sample_point(bitrate_nominal); - bitrate_error = abs(bitrate_nominal - bt.bitrate); sample_point_error = abs(sample_point_nominal - bt.sample_point); @@ -822,11 +838,44 @@ static void print_bit_timing(const struct calc_bittiming_const *btc, printf("%4.1f%% ", /* Sample Point Error */ 100.0 * sample_point_error / sample_point_nominal); - if (btc->printf_btr) - btc->printf_btr(&bt, false); + if (printf_btr) + printf_btr(&bt, false); printf("\n"); } +static void print_bittiming(const struct calc_data *data) +{ + const struct calc_ref_clk *ref_clks = data->ref_clks; + + while (ref_clks->clk) { + unsigned int const *bitrates = data->bitrates; + bool quiet = data->quiet; + + while (*bitrates) { + unsigned int sample_point; + + /* get nominal sample point */ + if (data->sample_point) + sample_point = data->sample_point; + else + sample_point = get_cia_sample_point(*bitrates); + + print_bittiming_one(data->bittiming_const, + data->opt_bt, + ref_clks, + *bitrates, + sample_point, + data->printf_btr, + quiet); + bitrates++; + quiet = true; + } + + printf("\n"); + ref_clks++; + } +} + static void do_list(void) { unsigned int i; @@ -835,51 +884,41 @@ static void do_list(void) printf("%s\n", can_calc_consts[i].bittiming_const.name); } -static void do_calc(const char *name, - const struct can_bittiming *opt_ref_bt, - __u32 bitrate_nominal, unsigned int spt_nominal, - struct calc_ref_clk *opt_ref_clk, bool quiet) +static void do_calc(struct calc_data *data) { - const struct calc_bittiming_const *btc; - const struct calc_ref_clk *ref_clk; - unsigned int i, j, k; + unsigned int i; bool found = false; for (i = 0; i < ARRAY_SIZE(can_calc_consts); i++) { - if (name && - strcmp(can_calc_consts[i].bittiming_const.name, name) != 0) + const struct calc_bittiming_const *btc; + + btc = &can_calc_consts[i]; + + if (data->name && strcmp(data->name, btc->bittiming_const.name)) continue; found = true; - btc = &can_calc_consts[i]; - for (j = 0; j < ARRAY_SIZE(btc->ref_clk); j++) { - if (opt_ref_clk) - ref_clk = opt_ref_clk; + if (btc->bittiming_const.name[0]) { + data->bittiming_const = &btc->bittiming_const; + data->printf_btr = btc->printf_btr; + + if (data->opt_ref_clk) + data->ref_clks = data->opt_ref_clk; else - ref_clk = &btc->ref_clk[j]; + data->ref_clks = btc->ref_clk; - if (!ref_clk->clk) - break; + if (data->opt_bitrates) + data->bitrates = data->opt_bitrates; + else + data->bitrates = common_bitrates; - if (bitrate_nominal) { - print_bit_timing(btc, opt_ref_bt, ref_clk, bitrate_nominal, - spt_nominal, quiet); - } else { - for (k = 0; k < ARRAY_SIZE(common_bitrates); k++) - print_bit_timing(btc, opt_ref_bt, ref_clk, - common_bitrates[k], - spt_nominal, k); - } - printf("\n"); - - if (opt_ref_clk) - break; + print_bittiming(data); } } if (!found) { - printf("error: unknown CAN controller '%s', try one of these:\n\n", name); + printf("error: unknown CAN controller '%s', try one of these:\n\n", data->name); do_list(); exit(EXIT_FAILURE); } @@ -887,18 +926,21 @@ static void do_calc(const char *name, int main(int argc, char *argv[]) { - __u32 bitrate_nominal = 0; - unsigned int spt_nominal = 0; - struct calc_ref_clk opt_ref_clk = { - .name = "cmd-line", + struct calc_ref_clk opt_ref_clk[] = { + { .name = "cmd-line" }, + { /* sentinel */ } }; - struct can_bittiming bt = { 0 }; - bool quiet = false, list = false; - const char *name = NULL; + struct can_bittiming opt_bt[1] = { }; + unsigned int opt_bitrate[] = { + 0, + 0 /* sentinel */ + }; + struct calc_data data[1] = { }; + bool list = false; int opt; const struct option long_options[] = { - { "tq", required_argument, 0, OPT_TQ, }, + { "tq", required_argument, 0, OPT_TQ, }, { "prop-seg", required_argument, 0, OPT_PROP_SEG, }, { "phase-seg1", required_argument, 0, OPT_PHASE_SEG1, }, { "phase-seg2", required_argument, 0, OPT_PHASE_SEG2, }, @@ -912,11 +954,11 @@ int main(int argc, char *argv[]) while ((opt = getopt_long(argc, argv, "b:c:lqs:?", long_options, NULL)) != -1) { switch (opt) { case 'b': - bitrate_nominal = atoi(optarg); + opt_bitrate[0] = strtoul(optarg, NULL, 10); break; case 'c': - opt_ref_clk.clk = strtoul(optarg, NULL, 10); + opt_ref_clk->clk = strtoul(optarg, NULL, 10); break; case 'l': @@ -924,11 +966,11 @@ int main(int argc, char *argv[]) break; case 'q': - quiet = true; + data->quiet = true; break; case 's': - spt_nominal = strtoul(optarg, NULL, 10); + data->sample_point = strtoul(optarg, NULL, 10); break; case '?': @@ -937,40 +979,40 @@ int main(int argc, char *argv[]) break; case OPT_TQ: - bt.tq = strtoul(optarg, NULL, 10); + opt_bt->tq = strtoul(optarg, NULL, 10); break; case OPT_PROP_SEG: - bt.prop_seg = strtoul(optarg, NULL, 10); + opt_bt->prop_seg = strtoul(optarg, NULL, 10); break; case OPT_PHASE_SEG1: - bt.phase_seg1 = strtoul(optarg, NULL, 10); + opt_bt->phase_seg1 = strtoul(optarg, NULL, 10); break; case OPT_PHASE_SEG2: - bt.phase_seg2 = strtoul(optarg, NULL, 10); + opt_bt->phase_seg2 = strtoul(optarg, NULL, 10); break; case OPT_SJW: - bt.sjw = strtoul(optarg, NULL, 10); + opt_bt->sjw = strtoul(optarg, NULL, 10); break; case OPT_BRP: - bt.brp = strtoul(optarg, NULL, 10); + opt_bt->brp = strtoul(optarg, NULL, 10); break; case OPT_TSEG1: { __u32 tseg1; tseg1 = strtoul(optarg, NULL, 10); - bt.prop_seg = tseg1 / 2; - bt.phase_seg1 = tseg1 - bt.prop_seg; + opt_bt->prop_seg = tseg1 / 2; + opt_bt->phase_seg1 = tseg1 - opt_bt->prop_seg; break; } case OPT_TSEG2: - bt.phase_seg2 = strtoul(optarg, NULL, 10); + opt_bt->phase_seg2 = strtoul(optarg, NULL, 10); break; default: @@ -986,23 +1028,24 @@ int main(int argc, char *argv[]) } if (argc == optind + 1) - name = argv[optind]; + data->name = argv[optind]; if (list) { do_list(); exit(EXIT_SUCCESS); } - if (spt_nominal && (spt_nominal >= 1000 || spt_nominal < 100)) { + if (data->sample_point && (data->sample_point >= 1000 || data->sample_point < 100)) print_usage(argv[0]); - exit(EXIT_FAILURE); - } - do_calc(name, - bt.prop_seg ? &bt: NULL, - bitrate_nominal, spt_nominal, - opt_ref_clk.clk ? &opt_ref_clk : NULL, - quiet); + if (opt_ref_clk->clk) + data->opt_ref_clk = opt_ref_clk; + if (opt_bitrate[0]) + data->opt_bitrates = opt_bitrate; + if (opt_bt->prop_seg) + data->opt_bt = opt_bt; + + do_calc(data); exit(EXIT_SUCCESS); } From 2829512f9b2454ca141fbeb10bb9162efd77168a Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Thu, 9 May 2019 11:04:36 +0200 Subject: [PATCH 06/15] can-calc-bit-timing: add nop printf_btr Signed-off-by: Marc Kleine-Budde --- can-calc-bit-timing.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/can-calc-bit-timing.c b/can-calc-bit-timing.c index 3f4057f..99e9d93 100644 --- a/can-calc-bit-timing.c +++ b/can-calc-bit-timing.c @@ -183,6 +183,10 @@ static void print_usage(char *cmd) cmd); } +static void printf_btr_nop(struct can_bittiming *bt, bool hdr) +{ +} + static void printf_btr_sja1000(struct can_bittiming *bt, bool hdr) { uint8_t btr0, btr1; @@ -791,8 +795,7 @@ static void print_bittiming_one(const struct can_bittiming_const *bittiming_cons ref_clk->name ? ")" : "", ref_clk->clk / 1000000.0); - if (printf_btr) - printf_btr(&bt, true); + printf_btr(&bt, true); printf("\n"); } @@ -838,8 +841,7 @@ static void print_bittiming_one(const struct can_bittiming_const *bittiming_cons printf("%4.1f%% ", /* Sample Point Error */ 100.0 * sample_point_error / sample_point_nominal); - if (printf_btr) - printf_btr(&bt, false); + printf_btr(&bt, false); printf("\n"); } @@ -848,9 +850,15 @@ static void print_bittiming(const struct calc_data *data) const struct calc_ref_clk *ref_clks = data->ref_clks; while (ref_clks->clk) { + void (*printf_btr)(struct can_bittiming *bt, bool hdr); unsigned int const *bitrates = data->bitrates; bool quiet = data->quiet; + if (data->printf_btr) + printf_btr = data->printf_btr; + else + printf_btr = printf_btr_nop; + while (*bitrates) { unsigned int sample_point; @@ -865,7 +873,7 @@ static void print_bittiming(const struct calc_data *data) ref_clks, *bitrates, sample_point, - data->printf_btr, + printf_btr, quiet); bitrates++; quiet = true; From 04123b3b36343ce1226040c1dd4ea54bfd2f1880 Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Tue, 18 Jan 2022 14:42:16 +0100 Subject: [PATCH 07/15] can-calc-bit-timing: print_bittiming(): skip bit timing without ref clock Signed-off-by: Marc Kleine-Budde --- can-calc-bit-timing.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/can-calc-bit-timing.c b/can-calc-bit-timing.c index 99e9d93..4890404 100644 --- a/can-calc-bit-timing.c +++ b/can-calc-bit-timing.c @@ -849,6 +849,10 @@ static void print_bittiming(const struct calc_data *data) { const struct calc_ref_clk *ref_clks = data->ref_clks; + if (!ref_clks->clk && !data->quiet) + printf("Skipping bit timing parameter calculation for %s, no ref clock defined\n\n", + data->bittiming_const->name); + while (ref_clks->clk) { void (*printf_btr)(struct can_bittiming *bt, bool hdr); unsigned int const *bitrates = data->bitrates; From 36d76ba07a41da1dd2201ac3f74ded8f613dca48 Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Thu, 9 May 2019 10:59:15 +0200 Subject: [PATCH 08/15] can-calc-bit-timing: add support for calculation of CAN-FD bit timings Signed-off-by: Marc Kleine-Budde --- can-calc-bit-timing.c | 60 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 48 insertions(+), 12 deletions(-) diff --git a/can-calc-bit-timing.c b/can-calc-bit-timing.c index 4890404..596e60f 100644 --- a/can-calc-bit-timing.c +++ b/can-calc-bit-timing.c @@ -120,10 +120,12 @@ struct calc_ref_clk { struct calc_bittiming_const { const struct can_bittiming_const bittiming_const; + const struct can_bittiming_const data_bittiming_const; const struct calc_ref_clk ref_clk[16]; const void (*printf_btr)(struct can_bittiming *bt, bool hdr); + const void (*printf_data_btr)(struct can_bittiming *bt, bool hdr); }; struct calc_data { @@ -554,6 +556,17 @@ static const unsigned int common_bitrates[] = { 0 }; +static const unsigned int common_data_bitrates[] = { + 12000000, + 10000000, + 8000000, + 5000000, + 4000000, + 2000000, + 1000000, + 0 +}; + #define CAN_CALC_MAX_ERROR 50 /* in one-tenth of a percent */ #define CAN_CALC_SYNC_SEG 1 @@ -787,8 +800,8 @@ static void print_bittiming_one(const struct can_bittiming_const *bittiming_cons if (!quiet) { printf("Bit timing parameters for %s%s%s%s with %.6f MHz ref clock\n" - "nominal real Bitrt nom real SampP\n" - "Bitrate TQ[ns] PrS PhS1 PhS2 SJW BRP Bitrate Error SampP SampP Error ", + " nominal real Bitrt nom real SampP\n" + " Bitrate TQ[ns] PrS PhS1 PhS2 SJW BRP Bitrate Error SampP SampP Error ", bittiming_const->name, ref_clk->name ? " (" : "", ref_clk->name ? ref_clk->name : "", @@ -803,12 +816,12 @@ static void print_bittiming_one(const struct can_bittiming_const *bittiming_cons bt = *ref_bt; if (can_fixup_bittiming(&dev, &bt, bittiming_const)) { - printf("%7d ***parameters exceed controller's range***\n", bitrate_nominal); + printf("%8d ***parameters exceed controller's range***\n", bitrate_nominal); return; } } else { if (can_calc_bittiming(&dev, &bt, bittiming_const)) { - printf("%7d ***bitrate not possible***\n", bitrate_nominal); + printf("%8d ***bitrate not possible***\n", bitrate_nominal); return; } } @@ -816,29 +829,29 @@ static void print_bittiming_one(const struct can_bittiming_const *bittiming_cons bitrate_error = abs(bitrate_nominal - bt.bitrate); sample_point_error = abs(sample_point_nominal - bt.sample_point); - printf("%7d " /* Bitrate */ + printf("%8d " /* Bitrate */ "%6d %3d %4d %4d " /* TQ[ns], PrS, PhS1, PhS2 */ "%3d %3d " /* SJW, BRP */ - "%7d ", /* real Bitrate */ + "%8d ", /* real Bitrate */ bitrate_nominal, bt.tq, bt.prop_seg, bt.phase_seg1, bt.phase_seg2, bt.sjw, bt.brp, bt.bitrate); if (100.0 * bitrate_error / bitrate_nominal > 99.9) - printf("≥100%% "); + printf("≥100%% "); else - printf("%4.1f%% ", + printf("%4.1f%% ", /* Bitrate Error */ 100.0 * bitrate_error / bitrate_nominal); - printf("%4.1f%% %4.1f%% ", /* nom Sample Point, real Sample Point */ + printf("%4.1f%% %4.1f%% ", /* nom Sample Point, real Sample Point */ sample_point_nominal / 10.0, bt.sample_point / 10.0); if (100.0 * sample_point_error / sample_point_nominal > 99.9) - printf("≥100%% "); + printf("≥100%% "); else - printf("%4.1f%% ", /* Sample Point Error */ + printf("%4.1f%% ", /* Sample Point Error */ 100.0 * sample_point_error / sample_point_nominal); printf_btr(&bt, false); @@ -906,7 +919,9 @@ static void do_calc(struct calc_data *data) btc = &can_calc_consts[i]; - if (data->name && strcmp(data->name, btc->bittiming_const.name)) + if (data->name && + strcmp(data->name, btc->bittiming_const.name) && + strcmp(data->name, btc->data_bittiming_const.name)) continue; found = true; @@ -927,6 +942,27 @@ static void do_calc(struct calc_data *data) print_bittiming(data); } + + if (btc->data_bittiming_const.name[0]) { + data->bittiming_const = &btc->data_bittiming_const; + + if (btc->printf_data_btr) + data->printf_btr = btc->printf_data_btr; + else + data->printf_btr = btc->printf_btr; + + if (data->opt_ref_clk) + data->ref_clks = data->opt_ref_clk; + else + data->ref_clks = btc->ref_clk; + + if (data->opt_bitrates) + data->bitrates = data->opt_bitrates; + else + data->bitrates = common_data_bitrates; + + print_bittiming(data); + } } if (!found) { From 046d9f88ee47c13ff1abca106263b60e16d9f678 Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Wed, 19 Jan 2022 06:49:04 +0100 Subject: [PATCH 09/15] can-calc-bit-timing: add option to specify explicit data bit timing --- can-calc-bit-timing.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/can-calc-bit-timing.c b/can-calc-bit-timing.c index 596e60f..ef6a1ad 100644 --- a/can-calc-bit-timing.c +++ b/can-calc-bit-timing.c @@ -140,6 +140,7 @@ struct calc_data { const struct calc_ref_clk *opt_ref_clk; const unsigned int *opt_bitrates; + const unsigned int *opt_data_bitrates; const struct can_bittiming *opt_bt; bool quiet; @@ -168,7 +169,8 @@ static void print_usage(char *cmd) "Options:\n" "\t-q don't print header line\n" "\t-l list all support CAN controller names\n" - "\t-b bit-rate in bits/sec\n" + "\t-b arbitration bit-rate in bits/sec\n" + "\t-d data bit-rate in bits/sec\n" "\t-s sample-point in one-tenth of a percent\n" "\t or 0 for CIA recommended sample points\n" "\t-c real CAN system clock in Hz\n" @@ -956,7 +958,9 @@ static void do_calc(struct calc_data *data) else data->ref_clks = btc->ref_clk; - if (data->opt_bitrates) + if (data->opt_data_bitrates) + data->bitrates = data->opt_data_bitrates; + else if (data->opt_bitrates) data->bitrates = data->opt_bitrates; else data->bitrates = common_data_bitrates; @@ -983,6 +987,10 @@ int main(int argc, char *argv[]) 0, 0 /* sentinel */ }; + unsigned int opt_data_bitrate[] = { + 0, + 0 /* sentinel */ + }; struct calc_data data[1] = { }; bool list = false; int opt; @@ -999,7 +1007,7 @@ int main(int argc, char *argv[]) { 0, 0, 0, 0 }, }; - while ((opt = getopt_long(argc, argv, "b:c:lqs:?", long_options, NULL)) != -1) { + while ((opt = getopt_long(argc, argv, "b:c:d:lqs:?", long_options, NULL)) != -1) { switch (opt) { case 'b': opt_bitrate[0] = strtoul(optarg, NULL, 10); @@ -1009,6 +1017,10 @@ int main(int argc, char *argv[]) opt_ref_clk->clk = strtoul(optarg, NULL, 10); break; + case 'd': + opt_data_bitrate[0] = strtoul(optarg, NULL, 10); + break; + case 'l': list = true; break; @@ -1090,6 +1102,8 @@ int main(int argc, char *argv[]) data->opt_ref_clk = opt_ref_clk; if (opt_bitrate[0]) data->opt_bitrates = opt_bitrate; + if (opt_data_bitrate[0]) + data->opt_data_bitrates = opt_data_bitrate; if (opt_bt->prop_seg) data->opt_bt = opt_bt; From 8d0158950011da9a3cfa661763e22a075795795f Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Mon, 3 Jun 2019 19:48:44 +0200 Subject: [PATCH 10/15] can-calc-bit-timing: move struct definitions Signed-off-by: Marc Kleine-Budde --- can-calc-bit-timing.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/can-calc-bit-timing.c b/can-calc-bit-timing.c index ef6a1ad..c90cc6f 100644 --- a/can-calc-bit-timing.c +++ b/can-calc-bit-timing.c @@ -118,6 +118,17 @@ struct calc_ref_clk { const char *name; }; +/* + * minimal structs, just enough to be source level compatible + */ +struct can_priv { + struct can_clock clock; +}; + +struct net_device { + struct can_priv priv; +}; + struct calc_bittiming_const { const struct can_bittiming_const bittiming_const; const struct can_bittiming_const data_bittiming_const; @@ -146,17 +157,6 @@ struct calc_data { bool quiet; }; -/* - * minimal structs, just enough to be source level compatible - */ -struct can_priv { - struct can_clock clock; -}; - -struct net_device { - struct can_priv priv; -}; - static inline void *netdev_priv(const struct net_device *dev) { return (void *)&dev->priv; From f9c9f6841b1ee52a62c6efb8195d8233593a0c95 Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Thu, 9 May 2019 16:21:59 +0200 Subject: [PATCH 11/15] can-calc-bit-timing: document kernel commit of current bit timing calculation algorithm Signed-off-by: Marc Kleine-Budde --- can-calc-bit-timing.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/can-calc-bit-timing.c b/can-calc-bit-timing.c index c90cc6f..77c3395 100644 --- a/can-calc-bit-timing.c +++ b/can-calc-bit-timing.c @@ -585,6 +585,17 @@ static const unsigned int common_data_bitrates[] = { * registers of the CAN controller. You can find more information * in the header file linux/can/netlink.h. */ + +/* + * imported from v4.8-rc1~140^2~304^2~11 + * + * 7da29f97d6c8 can: dev: can-calc-bit-timing(): better sample point calculation + */ +#undef can_update_spt +#undef can_calc_bittiming +#define can_update_spt can_update_spt_v4_8 +#define can_calc_bittiming can_calc_bittiming_v4_8 + static int can_update_spt(const struct can_bittiming_const *btc, unsigned int spt_nominal, unsigned int tseg, unsigned int *tseg1_ptr, unsigned int *tseg2_ptr, @@ -729,6 +740,9 @@ static int can_calc_bittiming(struct net_device *dev, struct can_bittiming *bt, return 0; } +#undef can_calc_bittiming +#undef can_update_spt + static int can_fixup_bittiming(struct net_device *dev, struct can_bittiming *bt, const struct can_bittiming_const *btc) { @@ -822,7 +836,7 @@ static void print_bittiming_one(const struct can_bittiming_const *bittiming_cons return; } } else { - if (can_calc_bittiming(&dev, &bt, bittiming_const)) { + if (can_calc_bittiming_v4_8(&dev, &bt, bittiming_const)) { printf("%8d ***bitrate not possible***\n", bitrate_nominal); return; } From f42e968bcf7d6cf2c12694b1062aaf01f846f24b Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Tue, 4 Jun 2019 10:15:02 +0200 Subject: [PATCH 12/15] can-calc-bit-timing: add support for additional bit timing calculation algorithms Signed-off-by: Marc Kleine-Budde --- can-calc-bit-timing.c | 78 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 70 insertions(+), 8 deletions(-) diff --git a/can-calc-bit-timing.c b/can-calc-bit-timing.c index 77c3395..3c18d09 100644 --- a/can-calc-bit-timing.c +++ b/can-calc-bit-timing.c @@ -38,6 +38,7 @@ enum { OPT_BRP, OPT_TSEG1, OPT_TSEG2, + OPT_ALG, }; /* imported from kernel */ @@ -139,8 +140,15 @@ struct calc_bittiming_const { const void (*printf_data_btr)(struct can_bittiming *bt, bool hdr); }; +struct can_calc_bittiming { + int (*alg)(struct net_device *dev, struct can_bittiming *bt, + const struct can_bittiming_const *btc); + const char *name; +}; + struct calc_data { const struct can_bittiming_const *bittiming_const; + const struct can_calc_bittiming *calc_bittiming; const void (*printf_btr)(struct can_bittiming *bt, bool hdr); const char *name; @@ -174,6 +182,7 @@ static void print_usage(char *cmd) "\t-s sample-point in one-tenth of a percent\n" "\t or 0 for CIA recommended sample points\n" "\t-c real CAN system clock in Hz\n" + "\t--alg choose specified algorithm for bit-timing calculation\n" "\n" "Or supply low level bit timing parameters to decode them:\n" "\n" @@ -743,6 +752,14 @@ static int can_calc_bittiming(struct net_device *dev, struct can_bittiming *bt, #undef can_calc_bittiming #undef can_update_spt +static const struct can_calc_bittiming calc_bittiming_list[] = { + /* 1st will be default */ + { + .alg = can_calc_bittiming_v4_8, + .name = "v4.8", + }, +}; + static int can_fixup_bittiming(struct net_device *dev, struct can_bittiming *bt, const struct can_bittiming_const *btc) { @@ -797,7 +814,8 @@ static __u32 get_cia_sample_point(__u32 bitrate) return sampl_pt; } -static void print_bittiming_one(const struct can_bittiming_const *bittiming_const, +static void print_bittiming_one(const struct can_calc_bittiming *calc_bittiming, + const struct can_bittiming_const *bittiming_const, const struct can_bittiming *ref_bt, const struct calc_ref_clk *ref_clk, unsigned int bitrate_nominal, @@ -815,14 +833,15 @@ static void print_bittiming_one(const struct can_bittiming_const *bittiming_cons unsigned int bitrate_error, sample_point_error; if (!quiet) { - printf("Bit timing parameters for %s%s%s%s with %.6f MHz ref clock\n" + printf("Bit timing parameters for %s with %.6f MHz ref clock %s%s%susing algo '%s'\n" " nominal real Bitrt nom real SampP\n" " Bitrate TQ[ns] PrS PhS1 PhS2 SJW BRP Bitrate Error SampP SampP Error ", bittiming_const->name, - ref_clk->name ? " (" : "", + ref_clk->clk / 1000000.0, + ref_clk->name ? "(" : "", ref_clk->name ? ref_clk->name : "", - ref_clk->name ? ")" : "", - ref_clk->clk / 1000000.0); + ref_clk->name ? ") " : "", + calc_bittiming->name); printf_btr(&bt, true); printf("\n"); @@ -836,7 +855,7 @@ static void print_bittiming_one(const struct can_bittiming_const *bittiming_cons return; } } else { - if (can_calc_bittiming_v4_8(&dev, &bt, bittiming_const)) { + if (calc_bittiming->alg(&dev, &bt, bittiming_const)) { printf("%8d ***bitrate not possible***\n", bitrate_nominal); return; } @@ -901,7 +920,8 @@ static void print_bittiming(const struct calc_data *data) else sample_point = get_cia_sample_point(*bitrates); - print_bittiming_one(data->bittiming_const, + print_bittiming_one(data->calc_bittiming, + data->bittiming_const, data->opt_bt, ref_clks, *bitrates, @@ -917,6 +937,14 @@ static void print_bittiming(const struct calc_data *data) } } +static void do_list_calc_bittiming_list(void) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(calc_bittiming_list); i++) + printf(" %s\n", calc_bittiming_list[i].name); +} + static void do_list(void) { unsigned int i; @@ -1005,7 +1033,12 @@ int main(int argc, char *argv[]) 0, 0 /* sentinel */ }; - struct calc_data data[1] = { }; + struct calc_data data[] = { + { + .calc_bittiming = calc_bittiming_list, + } + }; + const char *opt_alg_name = NULL; bool list = false; int opt; @@ -1018,6 +1051,7 @@ int main(int argc, char *argv[]) { "brp", required_argument, 0, OPT_BRP, }, { "tseg1", required_argument, 0, OPT_TSEG1, }, { "tseg2", required_argument, 0, OPT_TSEG2, }, + { "alg", optional_argument, 0, OPT_ALG, }, { 0, 0, 0, 0 }, }; @@ -1089,6 +1123,16 @@ int main(int argc, char *argv[]) opt_bt->phase_seg2 = strtoul(optarg, NULL, 10); break; + case OPT_ALG: + if (!optarg) { + printf("Supported CAN calc bit timing algorithms:\n\n"); + do_list_calc_bittiming_list(); + printf("\n"); + exit(EXIT_SUCCESS); + } + opt_alg_name = optarg; + break; + default: print_usage(basename(argv[0])); exit(EXIT_FAILURE); @@ -1112,6 +1156,24 @@ int main(int argc, char *argv[]) if (data->sample_point && (data->sample_point >= 1000 || data->sample_point < 100)) print_usage(argv[0]); + if (opt_alg_name) { + bool alg_found = false; + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(calc_bittiming_list); i++) { + if (!strcmp(opt_alg_name, calc_bittiming_list[i].name)) { + data->calc_bittiming = &calc_bittiming_list[i]; + alg_found = true; + } + } + + if (!alg_found) { + printf("error: unknown CAN calc bit timing algorithm '%s', try one of these:\n\n", opt_alg_name); + do_list_calc_bittiming_list(); + exit(EXIT_FAILURE); + } + } + if (opt_ref_clk->clk) data->opt_ref_clk = opt_ref_clk; if (opt_bitrate[0]) From 2636640aa77f399835a70ec7533eff251b562563 Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Mon, 3 Jun 2019 22:31:23 +0200 Subject: [PATCH 13/15] can-calc-bit-timing: import bit timing calculation algorithm from v3.18 Signed-off-by: Marc Kleine-Budde --- can-calc-bit-timing.c | 130 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+) diff --git a/can-calc-bit-timing.c b/can-calc-bit-timing.c index 3c18d09..5d4bc82 100644 --- a/can-calc-bit-timing.c +++ b/can-calc-bit-timing.c @@ -595,6 +595,133 @@ static const unsigned int common_data_bitrates[] = { * in the header file linux/can/netlink.h. */ +/* + * imported from v3.18-rc1~52^2~248^2~1 + * + * b25a437206ed can: dev: remove unused variable from can_calc_bittiming() function + */ +#undef can_calc_bittiming +#undef can_update_spt +#define can_calc_bittiming can_calc_bittiming_v3_18 +#define can_update_spt can_update_spt_v3_18 + +static int can_update_spt(const struct can_bittiming_const *btc, + int sampl_pt, int tseg, int *tseg1, int *tseg2) +{ + *tseg2 = tseg + 1 - (sampl_pt * (tseg + 1)) / 1000; + if (*tseg2 < btc->tseg2_min) + *tseg2 = btc->tseg2_min; + if (*tseg2 > btc->tseg2_max) + *tseg2 = btc->tseg2_max; + *tseg1 = tseg - *tseg2; + if (*tseg1 > btc->tseg1_max) { + *tseg1 = btc->tseg1_max; + *tseg2 = tseg - *tseg1; + } + return 1000 * (tseg + 1 - *tseg2) / (tseg + 1); +} + +static int can_calc_bittiming(struct net_device *dev, struct can_bittiming *bt, + const struct can_bittiming_const *btc) +{ + struct can_priv *priv = netdev_priv(dev); + long best_error = 1000000000, error = 0; + int best_tseg = 0, best_brp = 0, brp = 0; + int tsegall, tseg = 0, tseg1 = 0, tseg2 = 0; + int spt_error = 1000, spt = 0, sampl_pt; + long rate; + u64 v64; + + /* Use CIA recommended sample points */ + if (bt->sample_point) { + sampl_pt = bt->sample_point; + } else { + if (bt->bitrate > 800000) + sampl_pt = 750; + else if (bt->bitrate > 500000) + sampl_pt = 800; + else + sampl_pt = 875; + } + + /* tseg even = round down, odd = round up */ + for (tseg = (btc->tseg1_max + btc->tseg2_max) * 2 + 1; + tseg >= (btc->tseg1_min + btc->tseg2_min) * 2; tseg--) { + tsegall = 1 + tseg / 2; + /* Compute all possible tseg choices (tseg=tseg1+tseg2) */ + brp = priv->clock.freq / (tsegall * bt->bitrate) + tseg % 2; + /* chose brp step which is possible in system */ + brp = (brp / btc->brp_inc) * btc->brp_inc; + if ((brp < btc->brp_min) || (brp > btc->brp_max)) + continue; + rate = priv->clock.freq / (brp * tsegall); + error = bt->bitrate - rate; + /* tseg brp biterror */ + if (error < 0) + error = -error; + if (error > best_error) + continue; + best_error = error; + if (error == 0) { + spt = can_update_spt(btc, sampl_pt, tseg / 2, + &tseg1, &tseg2); + error = sampl_pt - spt; + if (error < 0) + error = -error; + if (error > spt_error) + continue; + spt_error = error; + } + best_tseg = tseg / 2; + best_brp = brp; + if (error == 0) + break; + } + + if (best_error) { + /* Error in one-tenth of a percent */ + error = (best_error * 1000) / bt->bitrate; + if (error > CAN_CALC_MAX_ERROR) { + netdev_err(dev, + "bitrate error %ld.%ld%% too high\n", + error / 10, error % 10); + return -EDOM; + } else { + netdev_warn(dev, "bitrate error %ld.%ld%%\n", + error / 10, error % 10); + } + } + + /* real sample point */ + bt->sample_point = can_update_spt(btc, sampl_pt, best_tseg, + &tseg1, &tseg2); + + v64 = (u64)best_brp * 1000000000UL; + do_div(v64, priv->clock.freq); + bt->tq = (u32)v64; + bt->prop_seg = tseg1 / 2; + bt->phase_seg1 = tseg1 - bt->prop_seg; + bt->phase_seg2 = tseg2; + + /* check for sjw user settings */ + if (!bt->sjw || !btc->sjw_max) + bt->sjw = 1; + else { + /* bt->sjw is at least 1 -> sanitize upper bound to sjw_max */ + if (bt->sjw > btc->sjw_max) + bt->sjw = btc->sjw_max; + /* bt->sjw must not be higher than tseg2 */ + if (tseg2 < bt->sjw) + bt->sjw = tseg2; + } + + bt->brp = best_brp; + /* real bit-rate */ + bt->bitrate = priv->clock.freq / (bt->brp * (tseg1 + tseg2 + 1)); + + return 0; +} + /* * imported from v4.8-rc1~140^2~304^2~11 * @@ -757,6 +884,9 @@ static const struct can_calc_bittiming calc_bittiming_list[] = { { .alg = can_calc_bittiming_v4_8, .name = "v4.8", + }, { + .alg = can_calc_bittiming_v3_18, + .name = "v3.18", }, }; From e7b5920b107e22a42efe26c37bd71e8d817477c1 Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Sat, 15 Jan 2022 23:31:25 +0100 Subject: [PATCH 14/15] can-calc-bit-timing: beautify btr register printing Signed-off-by: Marc Kleine-Budde --- can-calc-bit-timing.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/can-calc-bit-timing.c b/can-calc-bit-timing.c index 5d4bc82..9cf215a 100644 --- a/can-calc-bit-timing.c +++ b/can-calc-bit-timing.c @@ -205,7 +205,7 @@ static void printf_btr_sja1000(struct can_bittiming *bt, bool hdr) uint8_t btr0, btr1; if (hdr) { - printf("BTR0 BTR1"); + printf("%9s", "BTR0 BTR1"); } else { btr0 = ((bt->brp - 1) & 0x3f) | (((bt->sjw - 1) & 0x3) << 6); btr1 = ((bt->prop_seg + bt->phase_seg1 - 1) & 0xf) | @@ -260,7 +260,7 @@ static void printf_btr_mcp251x(struct can_bittiming *bt, bool hdr) static void printf_btr_mcp251xfd(struct can_bittiming *bt, bool hdr) { if (hdr) { - printf("NBTCFG"); + printf("%10s", "NBTCFG"); } else { uint32_t nbtcfg = ((bt->brp - 1) << 24) | ((bt->prop_seg + bt->phase_seg1 - 1) << 16) | @@ -327,7 +327,7 @@ static void printf_btr_bxcan(struct can_bittiming *bt, bool hdr) static void printf_btr_c_can(struct can_bittiming *bt, bool hdr) { if (hdr) { - printf("%s", " BTR BRPEXT"); + printf("%13s", "BTR BRPEXT"); } else { uint32_t btr; uint32_t brpext; From 66631a3e2374adf5bf7bac777bc4a76c1e799fa2 Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Tue, 18 Jan 2022 14:37:41 +0100 Subject: [PATCH 15/15] can-calc-bit-timing: add more bittiming constants and sort them Import all bit timing constants from the kernel (v5.16-rc1) and sort them by the occurrence in drivers/net/can/Makefile. Signed-off-by: Marc Kleine-Budde --- can-calc-bit-timing.c | 869 +++++++++++++++++++++++++++++++++++------- 1 file changed, 726 insertions(+), 143 deletions(-) diff --git a/can-calc-bit-timing.c b/can-calc-bit-timing.c index 9cf215a..dc2a62c 100644 --- a/can-calc-bit-timing.c +++ b/can-calc-bit-timing.c @@ -200,46 +200,24 @@ static void printf_btr_nop(struct can_bittiming *bt, bool hdr) { } -static void printf_btr_sja1000(struct can_bittiming *bt, bool hdr) -{ - uint8_t btr0, btr1; +#define RCAR_CAN_BCR_TSEG1(x) (((x) & 0x0f) << 20) +#define RCAR_CAN_BCR_BPR(x) (((x) & 0x3ff) << 8) +#define RCAR_CAN_BCR_SJW(x) (((x) & 0x3) << 4) +#define RCAR_CAN_BCR_TSEG2(x) ((x) & 0x07) - if (hdr) { - printf("%9s", "BTR0 BTR1"); - } else { - btr0 = ((bt->brp - 1) & 0x3f) | (((bt->sjw - 1) & 0x3) << 6); - btr1 = ((bt->prop_seg + bt->phase_seg1 - 1) & 0xf) | - (((bt->phase_seg2 - 1) & 0x7) << 4); - printf("0x%02x 0x%02x", btr0, btr1); - } -} - -static void printf_btr_at91(struct can_bittiming *bt, bool hdr) +static void printf_btr_rcar_can(struct can_bittiming *bt, bool hdr) { if (hdr) { - printf("%10s", "CAN_BR"); + printf("%10s", "CiBCR"); } else { - uint32_t br = ((bt->phase_seg2 - 1) | - ((bt->phase_seg1 - 1) << 4) | - ((bt->prop_seg - 1) << 8) | - ((bt->sjw - 1) << 12) | - ((bt->brp - 1) << 16)); - printf("0x%08x", br); - } -} + uint32_t bcr; -static void printf_btr_flexcan(struct can_bittiming *bt, bool hdr) -{ - if (hdr) { - printf("%10s", "CAN_CTRL"); - } else { - uint32_t ctrl = (((bt->brp - 1) << 24) | - ((bt->sjw - 1) << 22) | - ((bt->phase_seg1 - 1) << 19) | - ((bt->phase_seg2 - 1) << 16) | - ((bt->prop_seg - 1) << 0)); + bcr = RCAR_CAN_BCR_TSEG1(bt->phase_seg1 + bt->prop_seg - 1) | + RCAR_CAN_BCR_BPR(bt->brp - 1) | + RCAR_CAN_BCR_SJW(bt->sjw - 1) | + RCAR_CAN_BCR_TSEG2(bt->phase_seg2 - 1); - printf("0x%08x", ctrl); + printf("0x%08x", bcr << 8); } } @@ -270,44 +248,6 @@ static void printf_btr_mcp251xfd(struct can_bittiming *bt, bool hdr) } } -static void printf_btr_ti_hecc(struct can_bittiming *bt, bool hdr) -{ - if (hdr) { - printf("%10s", "CANBTC"); - } else { - uint32_t can_btc; - - can_btc = (bt->phase_seg2 - 1) & 0x7; - can_btc |= ((bt->phase_seg1 + bt->prop_seg - 1) - & 0xF) << 3; - can_btc |= ((bt->sjw - 1) & 0x3) << 8; - can_btc |= ((bt->brp - 1) & 0xFF) << 16; - - printf("0x%08x", can_btc); - } -} - -#define RCAR_CAN_BCR_TSEG1(x) (((x) & 0x0f) << 20) -#define RCAR_CAN_BCR_BPR(x) (((x) & 0x3ff) << 8) -#define RCAR_CAN_BCR_SJW(x) (((x) & 0x3) << 4) -#define RCAR_CAN_BCR_TSEG2(x) ((x) & 0x07) - -static void printf_btr_rcar_can(struct can_bittiming *bt, bool hdr) -{ - if (hdr) { - printf("%10s", "CiBCR"); - } else { - uint32_t bcr; - - bcr = RCAR_CAN_BCR_TSEG1(bt->phase_seg1 + bt->prop_seg - 1) | - RCAR_CAN_BCR_BPR(bt->brp - 1) | - RCAR_CAN_BCR_SJW(bt->sjw - 1) | - RCAR_CAN_BCR_TSEG2(bt->phase_seg2 - 1); - - printf("0x%08x", bcr << 8); - } -} - static void printf_btr_bxcan(struct can_bittiming *bt, bool hdr) { if (hdr) { @@ -324,6 +264,20 @@ static void printf_btr_bxcan(struct can_bittiming *bt, bool hdr) } } +static void printf_btr_at91(struct can_bittiming *bt, bool hdr) +{ + if (hdr) { + printf("%10s", "CAN_BR"); + } else { + uint32_t br = ((bt->phase_seg2 - 1) | + ((bt->phase_seg1 - 1) << 4) | + ((bt->prop_seg - 1) << 8) | + ((bt->sjw - 1) << 12) | + ((bt->brp - 1) << 16)); + printf("0x%08x", br); + } +} + static void printf_btr_c_can(struct can_bittiming *bt, bool hdr) { if (hdr) { @@ -342,6 +296,21 @@ static void printf_btr_c_can(struct can_bittiming *bt, bool hdr) } } +static void printf_btr_flexcan(struct can_bittiming *bt, bool hdr) +{ + if (hdr) { + printf("%10s", "CAN_CTRL"); + } else { + uint32_t ctrl = (((bt->brp - 1) << 24) | + ((bt->sjw - 1) << 22) | + ((bt->phase_seg1 - 1) << 19) | + ((bt->phase_seg2 - 1) << 16) | + ((bt->prop_seg - 1) << 0)); + + printf("0x%08x", ctrl); + } +} + static void printf_btr_mcan(struct can_bittiming *bt, bool hdr) { if (hdr) { @@ -359,82 +328,108 @@ static void printf_btr_mcan(struct can_bittiming *bt, bool hdr) } } +static void printf_btr_sja1000(struct can_bittiming *bt, bool hdr) +{ + uint8_t btr0, btr1; + + if (hdr) { + printf("%9s", "BTR0 BTR1"); + } else { + btr0 = ((bt->brp - 1) & 0x3f) | (((bt->sjw - 1) & 0x3) << 6); + btr1 = ((bt->prop_seg + bt->phase_seg1 - 1) & 0xf) | + (((bt->phase_seg2 - 1) & 0x7) << 4); + printf("0x%02x 0x%02x", btr0, btr1); + } +} + +static void printf_btr_ti_hecc(struct can_bittiming *bt, bool hdr) +{ + if (hdr) { + printf("%10s", "CANBTC"); + } else { + uint32_t can_btc; + + can_btc = (bt->phase_seg2 - 1) & 0x7; + can_btc |= ((bt->phase_seg1 + bt->prop_seg - 1) + & 0xF) << 3; + can_btc |= ((bt->sjw - 1) & 0x3) << 8; + can_btc |= ((bt->brp - 1) & 0xFF) << 16; + + printf("0x%08x", can_btc); + } +} + static const struct calc_bittiming_const can_calc_consts[] = { { .bittiming_const = { - .name = "sja1000", - .tseg1_min = 1, - .tseg1_max = 16, - .tseg2_min = 1, - .tseg2_max = 8, - .sjw_max = 4, - .brp_min = 1, - .brp_max = 64, - .brp_inc = 1, - }, - .ref_clk = { - { .clk = 8000000, }, - }, - .printf_btr = printf_btr_sja1000, - }, { - .bittiming_const = { - .name = "mscan", + .name = "rcar_can", .tseg1_min = 4, .tseg1_max = 16, .tseg2_min = 2, .tseg2_max = 8, .sjw_max = 4, .brp_min = 1, - .brp_max = 64, + .brp_max = 1024, .brp_inc = 1, }, .ref_clk = { - { .clk = 32000000, }, - { .clk = 33000000, }, - { .clk = 33300000, }, - { .clk = 33333333, }, - { .clk = 66660000, .name = "mpc5121", }, - { .clk = 66666666, .name = "mpc5121" }, + { .clk = 65000000, }, }, + .printf_btr = printf_btr_rcar_can, }, { .bittiming_const = { - .name = "at91", - .tseg1_min = 4, - .tseg1_max = 16, + .name = "rcar_canfd", + .tseg1_min = 2, + .tseg1_max = 128, .tseg2_min = 2, - .tseg2_max = 8, - .sjw_max = 4, - .brp_min = 2, - .brp_max = 128, + .tseg2_max = 32, + .sjw_max = 32, + .brp_min = 1, + .brp_max = 1024, .brp_inc = 1, }, - .ref_clk = { - { .clk = 99532800, .name = "ronetix PM9263", }, - { .clk = 100000000, }, - }, - .printf_btr = printf_btr_at91, - }, { - .bittiming_const = { - .name = "flexcan", - .tseg1_min = 4, + .data_bittiming_const = { + .name = "rcar_canfd", + .tseg1_min = 2, .tseg1_max = 16, .tseg2_min = 2, .tseg2_max = 8, - .sjw_max = 4, + .sjw_max = 8, .brp_min = 1, .brp_max = 256, .brp_inc = 1, }, .ref_clk = { - { .clk = 24000000, .name = "mx28" }, - { .clk = 30000000, .name = "mx6" }, - { .clk = 49875000, }, - { .clk = 66000000, }, - { .clk = 66500000, }, - { .clk = 66666666, }, - { .clk = 83368421, .name = "vybrid" }, + { .clk = 20000000, .name = "CIA recommendation"}, + { .clk = 40000000, .name = "CIA recommendation"}, + }, + }, { + .bittiming_const = { + .name = "rcar_canfd (CC)", + .tseg1_min = 4, + .tseg1_max = 16, + .tseg2_min = 2, + .tseg2_max = 8, + .sjw_max = 4, + .brp_min = 1, + .brp_max = 1024, + .brp_inc = 1, + }, + }, { /* -------- SPI -------- */ + .bittiming_const = { + .name = "hi311x", + .tseg1_min = 2, + .tseg1_max = 16, + .tseg2_min = 2, + .tseg2_max = 8, + .sjw_max = 4, + .brp_min = 1, + .brp_max = 64, + .brp_inc = 1, + }, + .ref_clk = { + { .clk = 24000000, }, }, - .printf_btr = printf_btr_flexcan, }, { .bittiming_const = { .name = "mcp251x", @@ -466,33 +461,28 @@ static const struct calc_bittiming_const can_calc_consts[] = { .brp_max = 256, .brp_inc = 1, }, - .ref_clk = { - { .clk = 20000000, }, - { .clk = 40000000, }, - }, - .printf_btr = printf_btr_mcp251xfd, - }, { - .bittiming_const = { - .name = "ti_hecc", + .data_bittiming_const = { + .name = "mcp251xfd", .tseg1_min = 1, - .tseg1_max = 16, + .tseg1_max = 32, .tseg2_min = 1, - .tseg2_max = 8, - .sjw_max = 4, + .tseg2_max = 16, + .sjw_max = 16, .brp_min = 1, .brp_max = 256, .brp_inc = 1, }, .ref_clk = { - { .clk = 13000000, }, + { .clk = 20000000, .name = "CIA recommendation"}, + { .clk = 40000000, .name = "CIA recommendation"}, }, - .printf_btr = printf_btr_ti_hecc, - }, { + .printf_btr = printf_btr_mcp251xfd, + }, { /* -------- USB -------- */ .bittiming_const = { - .name = "rcar_can", - .tseg1_min = 4, + .name = "usb_8dev", + .tseg1_min = 1, .tseg1_max = 16, - .tseg2_min = 2, + .tseg2_min = 1, .tseg2_max = 8, .sjw_max = 4, .brp_min = 1, @@ -500,12 +490,55 @@ static const struct calc_bittiming_const can_calc_consts[] = { .brp_inc = 1, }, .ref_clk = { - { .clk = 65000000, }, - }, - .printf_btr = printf_btr_rcar_can, + { .clk = 32000000, }, + } }, { .bittiming_const = { - .name = "bxcan", + .name = "ems_usb", + .tseg1_min = 1, + .tseg1_max = 16, + .tseg2_min = 1, + .tseg2_max = 8, + .sjw_max = 4, + .brp_min = 1, + .brp_max = 64, + .brp_inc = 1, + }, + .ref_clk = { + { .clk = 8000000, }, + }, + }, { + +#define ESD_USB2_TSEG1_MIN 1 +#define ESD_USB2_TSEG1_MAX 16 +#define ESD_USB2_TSEG2_MIN 1 +#define ESD_USB2_TSEG2_MAX 8 +#define ESD_USB2_SJW_MAX 4 +#define ESD_USB2_BRP_MIN 1 +#define ESD_USB2_BRP_MAX 1024 +#define ESD_USB2_BRP_INC 1 + +#define ESD_USB2_CAN_CLOCK 60000000 +#define ESD_USBM_CAN_CLOCK 36000000 + + .bittiming_const = { + .name = "esd_usb2", + .tseg1_min = ESD_USB2_TSEG1_MIN, + .tseg1_max = ESD_USB2_TSEG1_MAX, + .tseg2_min = ESD_USB2_TSEG2_MIN, + .tseg2_max = ESD_USB2_TSEG2_MAX, + .sjw_max = ESD_USB2_SJW_MAX, + .brp_min = ESD_USB2_BRP_MIN, + .brp_max = ESD_USB2_BRP_MAX, + .brp_inc = ESD_USB2_BRP_INC, + }, + .ref_clk = { + { .clk = ESD_USB2_CAN_CLOCK, .name = "CAN-USB/2", }, + { .clk = ESD_USBM_CAN_CLOCK, .name = "CAN-USB/Micro", }, + }, + }, { /* gs_usb */ + .bittiming_const = { + .name = "bxcan", // stm32f072 .tseg1_min = 1, .tseg1_max = 16, .tseg2_min = 1, @@ -519,6 +552,199 @@ static const struct calc_bittiming_const can_calc_consts[] = { { .clk = 48000000, }, }, .printf_btr = printf_btr_bxcan, + }, { /* gs_usb */ + .bittiming_const = { + .name = "CANtact Pro", // LPC65616 + .tseg1_min = 1, + .tseg1_max = 16, + .tseg2_min = 1, + .tseg2_max = 8, + .sjw_max = 4, + .brp_min = 1, + .brp_max = 1024, + .brp_inc = 1, + }, + .data_bittiming_const = { + .name = "CANtact Pro", // LPC65616 + .tseg1_min = 1, + .tseg1_max = 16, + .tseg2_min = 1, + .tseg2_max = 8, + .sjw_max = 4, + .brp_min = 1, + .brp_max = 1024, + .brp_inc = 1, + }, + .ref_clk = { + { .clk = 24000000, .name = "CANtact Pro (original)", }, + { .clk = 40000000, .name = "CIA recommendation"}, + }, + }, { + +#define KVASER_USB_TSEG1_MIN 1 +#define KVASER_USB_TSEG1_MAX 16 +#define KVASER_USB_TSEG2_MIN 1 +#define KVASER_USB_TSEG2_MAX 8 +#define KVASER_USB_SJW_MAX 4 +#define KVASER_USB_BRP_MIN 1 +#define KVASER_USB_BRP_MAX 64 +#define KVASER_USB_BRP_INC 1 + + .bittiming_const = { + .name = "kvaser_usb", + .tseg1_min = KVASER_USB_TSEG1_MIN, + .tseg1_max = KVASER_USB_TSEG1_MAX, + .tseg2_min = KVASER_USB_TSEG2_MIN, + .tseg2_max = KVASER_USB_TSEG2_MAX, + .sjw_max = KVASER_USB_SJW_MAX, + .brp_min = KVASER_USB_BRP_MIN, + .brp_max = KVASER_USB_BRP_MAX, + .brp_inc = KVASER_USB_BRP_INC, + }, + .ref_clk = { + { .clk = 8000000, }, + }, + }, { + .bittiming_const = { + .name = "kvaser_usb_kcan", + .tseg1_min = 1, + .tseg1_max = 255, + .tseg2_min = 1, + .tseg2_max = 32, + .sjw_max = 16, + .brp_min = 1, + .brp_max = 8192, + .brp_inc = 1, + }, + .data_bittiming_const = { + .name = "kvaser_usb_kcan", + .tseg1_min = 1, + .tseg1_max = 255, + .tseg2_min = 1, + .tseg2_max = 32, + .sjw_max = 16, + .brp_min = 1, + .brp_max = 8192, + .brp_inc = 1, + }, + .ref_clk = { + { .clk = 80000000, }, + }, + }, { + .bittiming_const = { + .name = "kvaser_usb_flex", + .tseg1_min = 4, + .tseg1_max = 16, + .tseg2_min = 2, + .tseg2_max = 8, + .sjw_max = 4, + .brp_min = 1, + .brp_max = 256, + .brp_inc = 1, + }, + .ref_clk = { + { .clk = 24000000, }, + }, + }, { + .bittiming_const = { + .name = "pcan_usb_pro", + .tseg1_min = 1, + .tseg1_max = 16, + .tseg2_min = 1, + .tseg2_max = 8, + .sjw_max = 4, + .brp_min = 1, + .brp_max = 1024, + .brp_inc = 1, + }, + .ref_clk = { + { .clk = 56000000, }, + }, + }, { + +#define PUCAN_TSLOW_BRP_BITS 10 +#define PUCAN_TSLOW_TSGEG1_BITS 8 +#define PUCAN_TSLOW_TSGEG2_BITS 7 +#define PUCAN_TSLOW_SJW_BITS 7 + +#define PUCAN_TFAST_BRP_BITS 10 +#define PUCAN_TFAST_TSGEG1_BITS 5 +#define PUCAN_TFAST_TSGEG2_BITS 4 +#define PUCAN_TFAST_SJW_BITS 4 + + .bittiming_const = { + .name = "pcan_usb_fd", + .tseg1_min = 1, + .tseg1_max = (1 << PUCAN_TSLOW_TSGEG1_BITS), + .tseg2_min = 1, + .tseg2_max = (1 << PUCAN_TSLOW_TSGEG2_BITS), + .sjw_max = (1 << PUCAN_TSLOW_SJW_BITS), + .brp_min = 1, + .brp_max = (1 << PUCAN_TSLOW_BRP_BITS), + .brp_inc = 1, + }, + .data_bittiming_const = { + .name = "pcan_usb_fd", + .tseg1_min = 1, + .tseg1_max = (1 << PUCAN_TFAST_TSGEG1_BITS), + .tseg2_min = 1, + .tseg2_max = (1 << PUCAN_TFAST_TSGEG2_BITS), + .sjw_max = (1 << PUCAN_TFAST_SJW_BITS), + .brp_min = 1, + .brp_max = (1 << PUCAN_TFAST_BRP_BITS), + .brp_inc = 1, + }, + .ref_clk = { + { .clk = 80000000, }, + }, + }, { + .bittiming_const = { + .name = "softing", + .tseg1_min = 1, + .tseg1_max = 16, + .tseg2_min = 1, + .tseg2_max = 8, + .sjw_max = 4, + .brp_min = 1, + .brp_max = 32, + .brp_inc = 1, + }, + .ref_clk = { + { .clk = 8000000, }, + { .clk = 16000000, }, + }, + }, { + .bittiming_const = { + .name = "at91", + .tseg1_min = 4, + .tseg1_max = 16, + .tseg2_min = 2, + .tseg2_max = 8, + .sjw_max = 4, + .brp_min = 2, + .brp_max = 128, + .brp_inc = 1, + }, + .ref_clk = { + { .clk = 99532800, .name = "ronetix PM9263", }, + { .clk = 100000000, }, + }, + .printf_btr = printf_btr_at91, + }, { + .bittiming_const = { + .name = "cc770", + .tseg1_min = 1, + .tseg1_max = 16, + .tseg2_min = 1, + .tseg2_max = 8, + .sjw_max = 4, + .brp_min = 1, + .brp_max = 64, + .brp_inc = 1, + }, + .ref_clk = { + { .clk = 8000000 }, + } }, { .bittiming_const = { .name = "c_can", @@ -535,6 +761,194 @@ static const struct calc_bittiming_const can_calc_consts[] = { { .clk = 24000000, }, }, .printf_btr = printf_btr_c_can, + }, { + .bittiming_const = { + .name = "flexcan", + .tseg1_min = 4, + .tseg1_max = 16, + .tseg2_min = 2, + .tseg2_max = 8, + .sjw_max = 4, + .brp_min = 1, + .brp_max = 256, + .brp_inc = 1, + }, + .ref_clk = { + { .clk = 24000000, .name = "mx28" }, + { .clk = 30000000, .name = "mx6" }, + { .clk = 49875000, }, + { .clk = 66000000, }, + { .clk = 66500000, .name = "mx25"}, + { .clk = 66666666, }, + { .clk = 83368421, .name = "vybrid" }, + }, + .printf_btr = printf_btr_flexcan, + }, { + .bittiming_const = { + .name = "flexcan-fd", + .tseg1_min = 2, + .tseg1_max = 96, + .tseg2_min = 2, + .tseg2_max = 32, + .sjw_max = 16, + .brp_min = 1, + .brp_max = 1024, + .brp_inc = 1, + }, + .data_bittiming_const = { + .name = "flexcan-fd", + .tseg1_min = 2, + .tseg1_max = 39, + .tseg2_min = 2, + .tseg2_max = 8, + .sjw_max = 4, + .brp_min = 1, + .brp_max = 1024, + .brp_inc = 1, + }, + .ref_clk = { + { .clk = 20000000, .name = "CIA recommendation"}, + { .clk = 40000000, .name = "CIA recommendation"}, + }, + }, { + +#define GRCAN_CONF_PS1_MIN 1 +#define GRCAN_CONF_PS1_MAX 15 +#define GRCAN_CONF_PS2_MIN 2 +#define GRCAN_CONF_PS2_MAX 8 +#define GRCAN_CONF_RSJ_MAX 4 +#define GRCAN_CONF_SCALER_MIN 0 +#define GRCAN_CONF_SCALER_MAX 255 +#define GRCAN_CONF_SCALER_INC 1 + + .bittiming_const = { + .name = "grcan", + .tseg1_min = GRCAN_CONF_PS1_MIN + 1, + .tseg1_max = GRCAN_CONF_PS1_MAX + 1, + .tseg2_min = GRCAN_CONF_PS2_MIN, + .tseg2_max = GRCAN_CONF_PS2_MAX, + .sjw_max = GRCAN_CONF_RSJ_MAX, + .brp_min = GRCAN_CONF_SCALER_MIN + 1, + .brp_max = GRCAN_CONF_SCALER_MAX + 1, + .brp_inc = GRCAN_CONF_SCALER_INC, + }, + }, { + .bittiming_const = { + .name = "ifi_canfd", + .tseg1_min = 1, + .tseg1_max = 256, + .tseg2_min = 2, + .tseg2_max = 256, + .sjw_max = 128, + .brp_min = 2, + .brp_max = 512, + .brp_inc = 1, + }, + .data_bittiming_const = { + .name = "ifi_canfd", + .tseg1_min = 1, + .tseg1_max = 256, + .tseg2_min = 2, + .tseg2_max = 256, + .sjw_max = 128, + .brp_min = 2, + .brp_max = 512, + .brp_inc = 1, + }, + .ref_clk = { + { .clk = 20000000, .name = "CIA recommendation"}, + { .clk = 40000000, .name = "CIA recommendation"}, + }, + }, { + .bittiming_const = { + .name = "janz-ican3", + .tseg1_min = 1, + .tseg1_max = 16, + .tseg2_min = 1, + .tseg2_max = 8, + .sjw_max = 4, + .brp_min = 1, + .brp_max = 64, + .brp_inc = 1, + }, + .ref_clk = { + { .clk = 8000000, }, + }, + }, { + .bittiming_const = { + .name = "kvaser_pciefd", + .tseg1_min = 1, + .tseg1_max = 512, + .tseg2_min = 1, + .tseg2_max = 32, + .sjw_max = 16, + .brp_min = 1, + .brp_max = 8192, + .brp_inc = 1, + }, + .data_bittiming_const = { + .name = "kvaser_pciefd", + .tseg1_min = 1, + .tseg1_max = 512, + .tseg2_min = 1, + .tseg2_max = 32, + .sjw_max = 16, + .brp_min = 1, + .brp_max = 8192, + .brp_inc = 1, + }, + .ref_clk = { + { .clk = 20000000, .name = "CIA recommendation"}, + { .clk = 40000000, .name = "CIA recommendation"}, + }, + }, { + .bittiming_const = { + .name = "mscan", + .tseg1_min = 4, + .tseg1_max = 16, + .tseg2_min = 2, + .tseg2_max = 8, + .sjw_max = 4, + .brp_min = 1, + .brp_max = 64, + .brp_inc = 1, + }, + .ref_clk = { + { .clk = 32000000, }, + { .clk = 33000000, }, + { .clk = 33300000, }, + { .clk = 33333333, }, + { .clk = 66660000, .name = "mpc5121", }, + { .clk = 66666666, .name = "mpc5121" }, + }, + }, { + .bittiming_const = { + .name = "mcan-v3.0", + .tseg1_min = 2, + .tseg1_max = 64, + .tseg2_min = 1, + .tseg2_max = 16, + .sjw_max = 16, + .brp_min = 1, + .brp_max = 1024, + .brp_inc = 1, + }, + .data_bittiming_const = { + .name = "mcan-v3.0", + .tseg1_min = 2, + .tseg1_max = 16, + .tseg2_min = 1, + .tseg2_max = 8, + .sjw_max = 4, + .brp_min = 1, + .brp_max = 32, + .brp_inc = 1, + }, + .ref_clk = { + { .clk = 20000000, .name = "CIA recommendation"}, + { .clk = 40000000, .name = "CIA recommendation"}, + }, + .printf_btr = printf_btr_mcan, }, { .bittiming_const = { .name = "mcan-v3.1+", @@ -547,10 +961,179 @@ static const struct calc_bittiming_const can_calc_consts[] = { .brp_max = 512, .brp_inc = 1, }, + .data_bittiming_const = { + .name = "mcan-v3.1+", + .tseg1_min = 1, + .tseg1_max = 32, + .tseg2_min = 1, + .tseg2_max = 16, + .sjw_max = 16, + .brp_min = 1, + .brp_max = 32, + .brp_inc = 1, + }, .ref_clk = { - { .clk = 40000000, }, + { .clk = 20000000, .name = "CIA recommendation"}, + { .clk = 40000000, .name = "CIA recommendation"}, + { .clk = 24000000, .name = "stm32mp1 - ck_hse" }, + { .clk = 24573875, .name = "stm32mp1 - pll3_1" }, + { .clk = 74250000, .name = "stm32mp1 - pll4_r" }, + { .clk = 29700000, .name = "stm32mp1 - pll4_q" }, }, .printf_btr = printf_btr_mcan, + }, { + +#define PUCAN_TSLOW_BRP_BITS 10 +#define PUCAN_TSLOW_TSGEG1_BITS 8 +#define PUCAN_TSLOW_TSGEG2_BITS 7 +#define PUCAN_TSLOW_SJW_BITS 7 + +#define PUCAN_TFAST_BRP_BITS 10 +#define PUCAN_TFAST_TSGEG1_BITS 5 +#define PUCAN_TFAST_TSGEG2_BITS 4 +#define PUCAN_TFAST_SJW_BITS 4 + + .bittiming_const = { + .name = "peak_canfd", + .tseg1_min = 1, + .tseg1_max = (1 << PUCAN_TSLOW_TSGEG1_BITS), + .tseg2_min = 1, + .tseg2_max = (1 << PUCAN_TSLOW_TSGEG2_BITS), + .sjw_max = (1 << PUCAN_TSLOW_SJW_BITS), + .brp_min = 1, + .brp_max = (1 << PUCAN_TSLOW_BRP_BITS), + .brp_inc = 1, + }, + .data_bittiming_const = { + .name = "peak_canfd", + .tseg1_min = 1, + .tseg1_max = (1 << PUCAN_TFAST_TSGEG1_BITS), + .tseg2_min = 1, + .tseg2_max = (1 << PUCAN_TFAST_TSGEG2_BITS), + .sjw_max = (1 << PUCAN_TFAST_SJW_BITS), + .brp_min = 1, + .brp_max = (1 << PUCAN_TFAST_BRP_BITS), + .brp_inc = 1, + }, + .ref_clk = { + { .clk = 20000000, }, + { .clk = 24000000, }, + { .clk = 30000000, }, + { .clk = 40000000, }, + { .clk = 60000000, }, + { .clk = 80000000, }, + }, + }, { + .bittiming_const = { + .name = "sja1000", + .tseg1_min = 1, + .tseg1_max = 16, + .tseg2_min = 1, + .tseg2_max = 8, + .sjw_max = 4, + .brp_min = 1, + .brp_max = 64, + .brp_inc = 1, + }, + .ref_clk = { + { .clk = 16000000 / 2, }, + { .clk = 24000000 / 2, .name = "f81601" }, + }, + .printf_btr = printf_btr_sja1000, + }, { + .bittiming_const = { + .name = "sun4i_can", + .tseg1_min = 1, + .tseg1_max = 16, + .tseg2_min = 1, + .tseg2_max = 8, + .sjw_max = 4, + .brp_min = 1, + .brp_max = 64, + .brp_inc = 1, + }, + }, { + .bittiming_const = { + .name = "ti_hecc", + .tseg1_min = 1, + .tseg1_max = 16, + .tseg2_min = 1, + .tseg2_max = 8, + .sjw_max = 4, + .brp_min = 1, + .brp_max = 256, + .brp_inc = 1, + }, + .ref_clk = { + { .clk = 13000000, }, + }, + .printf_btr = printf_btr_ti_hecc, + }, { + .bittiming_const = { + .name = "xilinx_can", + .tseg1_min = 1, + .tseg1_max = 16, + .tseg2_min = 1, + .tseg2_max = 8, + .sjw_max = 4, + .brp_min = 1, + .brp_max = 256, + .brp_inc = 1, + }, + }, { + .bittiming_const = { + .name = "xilinx_can_fd", + .tseg1_min = 1, + .tseg1_max = 64, + .tseg2_min = 1, + .tseg2_max = 16, + .sjw_max = 16, + .brp_min = 1, + .brp_max = 256, + .brp_inc = 1, + }, + .data_bittiming_const = { + .name = "xilinx_can_fd", + .tseg1_min = 1, + .tseg1_max = 16, + .tseg2_min = 1, + .tseg2_max = 8, + .sjw_max = 8, + .brp_min = 1, + .brp_max = 256, + .brp_inc = 1, + }, + .ref_clk = { + { .clk = 20000000, .name = "CIA recommendation"}, + { .clk = 40000000, .name = "CIA recommendation"}, + }, + }, { + .bittiming_const = { + .name = "xilinx_can_fd2", + .tseg1_min = 1, + .tseg1_max = 256, + .tseg2_min = 1, + .tseg2_max = 128, + .sjw_max = 128, + .brp_min = 2, + .brp_max = 256, + .brp_inc = 1, + }, + .data_bittiming_const = { + .name = "xilinx_can_fd2", + .tseg1_min = 1, + .tseg1_max = 32, + .tseg2_min = 1, + .tseg2_max = 16, + .sjw_max = 16, + .brp_min = 2, + .brp_max = 256, + .brp_inc = 1, + }, + .ref_clk = { + { .clk = 20000000, .name = "CIA recommendation"}, + { .clk = 40000000, .name = "CIA recommendation"}, + }, }, };