]> rtime.felk.cvut.cz Git - can-utils.git/blob - can-calc-bit-timing.c
can-calc-bit-timing: import helper macros from kernel
[can-utils.git] / can-calc-bit-timing.c
1 /* can-calc-bit-timing.c: Calculate CAN bit timing parameters
2  *
3  * Copyright (C) 2008 Wolfgang Grandegger <wg@grandegger.com>
4  *
5  * Derived from:
6  *   can_baud.c - CAN baudrate calculation
7  *   Code based on LinCAN sources and H8S2638 project
8  *   Copyright 2004-2006 Pavel Pisa - DCE FELK CVUT cz
9  *   Copyright 2005      Stanislav Marek
10  *   email:pisa@cmp.felk.cvut.cz
11  *
12  * This program is free software; you can redistribute it and/or modify
13  * it under the terms of the GNU General Public License as published by
14  * the Free Software Foundation; either version 2 of the License, or
15  * any later version.
16  */
17
18 #include <errno.h>
19 #include <getopt.h>
20 #include <stdbool.h>
21 #include <stdint.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25
26 #include <linux/types.h>
27 #include <linux/can/netlink.h>
28
29 /* imported from kernel */
30
31 /**
32  * abs - return absolute value of an argument
33  * @x: the value.  If it is unsigned type, it is converted to signed type first.
34  *     char is treated as if it was signed (regardless of whether it really is)
35  *     but the macro's return type is preserved as char.
36  *
37  * Return: an absolute value of x.
38  */
39 #define abs(x)  __abs_choose_expr(x, long long,                         \
40                 __abs_choose_expr(x, long,                              \
41                 __abs_choose_expr(x, int,                               \
42                 __abs_choose_expr(x, short,                             \
43                 __abs_choose_expr(x, char,                              \
44                 __builtin_choose_expr(                                  \
45                         __builtin_types_compatible_p(typeof(x), char),  \
46                         (char)({ signed char __x = (x); __x<0?-__x:__x; }), \
47                         ((void)0)))))))
48
49 #define __abs_choose_expr(x, type, other) __builtin_choose_expr(        \
50         __builtin_types_compatible_p(typeof(x),   signed type) ||       \
51         __builtin_types_compatible_p(typeof(x), unsigned type),         \
52         ({ signed type __x = (x); __x < 0 ? -__x : __x; }), other)
53
54 /*
55  * min()/max()/clamp() macros that also do
56  * strict type-checking.. See the
57  * "unnecessary" pointer comparison.
58  */
59 #define min(x, y) ({                            \
60         typeof(x) _min1 = (x);                  \
61         typeof(y) _min2 = (y);                  \
62         (void) (&_min1 == &_min2);              \
63         _min1 < _min2 ? _min1 : _min2; })
64
65 #define max(x, y) ({                            \
66         typeof(x) _max1 = (x);                  \
67         typeof(y) _max2 = (y);                  \
68         (void) (&_max1 == &_max2);              \
69         _max1 > _max2 ? _max1 : _max2; })
70
71 /**
72  * clamp - return a value clamped to a given range with strict typechecking
73  * @val: current value
74  * @lo: lowest allowable value
75  * @hi: highest allowable value
76  *
77  * This macro does strict typechecking of lo/hi to make sure they are of the
78  * same type as val.  See the unnecessary pointer comparisons.
79  */
80 #define clamp(val, lo, hi) min((typeof(val))max(val, lo), hi)
81
82 # define do_div(n,base) ({                                      \
83         uint32_t __base = (base);                               \
84         uint32_t __rem;                                         \
85         __rem = ((uint64_t)(n)) % __base;                       \
86         (n) = ((uint64_t)(n)) / __base;                         \
87         __rem;                                                  \
88  })
89
90 /* */
91
92 #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
93
94 /* we don't want to see these prints */
95 #define dev_err(dev, format, arg...)    do { } while (0)
96 #define dev_warn(dev, format, arg...)   do { } while (0)
97
98 /* define in-kernel-types */
99 typedef __u64 u64;
100 typedef __u32 u32;
101
102 struct calc_bittiming_const {
103         struct can_bittiming_const bittiming_const;
104
105         __u32 ref_clk;          /* CAN system clock frequency in Hz */
106         void (*printf_btr)(struct can_bittiming *bt, bool hdr);
107 };
108
109 /*
110  * minimal structs, just enough to be source level compatible
111  */
112 struct can_priv {
113         const struct can_bittiming_const *bittiming_const;
114         struct can_clock clock;
115 };
116
117 struct net_device {
118         struct can_priv priv;
119 };
120
121 static inline void *netdev_priv(const struct net_device *dev)
122 {
123         return (void *)&dev->priv;
124 }
125
126 static void print_usage(char *cmd)
127 {
128         printf("Usage: %s [options] [<CAN-contoller-name>]\n"
129                "\tOptions:\n"
130                "\t-q           : don't print header line\n"
131                "\t-l           : list all support CAN controller names\n"
132                "\t-b <bitrate> : bit-rate in bits/sec\n"
133                "\t-s <samp_pt> : sample-point in one-tenth of a percent\n"
134                "\t               or 0 for CIA recommended sample points\n"
135                "\t-c <clock>   : real CAN system clock in Hz\n",
136                cmd);
137
138         exit(EXIT_FAILURE);
139 }
140
141 static void printf_btr_sja1000(struct can_bittiming *bt, bool hdr)
142 {
143         uint8_t btr0, btr1;
144
145         if (hdr) {
146                 printf("BTR0 BTR1");
147         } else {
148                 btr0 = ((bt->brp - 1) & 0x3f) | (((bt->sjw - 1) & 0x3) << 6);
149                 btr1 = ((bt->prop_seg + bt->phase_seg1 - 1) & 0xf) |
150                         (((bt->phase_seg2 - 1) & 0x7) << 4);
151                 printf("0x%02x 0x%02x", btr0, btr1);
152         }
153 }
154
155 static void printf_btr_at91(struct can_bittiming *bt, bool hdr)
156 {
157         if (hdr) {
158                 printf("%10s", "CAN_BR");
159         } else {
160                 uint32_t br = ((bt->phase_seg2 - 1) |
161                                ((bt->phase_seg1 - 1) << 4) |
162                                ((bt->prop_seg - 1) << 8) |
163                                ((bt->sjw - 1) << 12) |
164                                ((bt->brp - 1) << 16));
165                 printf("0x%08x", br);
166         }
167 }
168
169 static void printf_btr_flexcan(struct can_bittiming *bt, bool hdr)
170 {
171         if (hdr) {
172                 printf("%10s", "CAN_CTRL");
173         } else {
174                 uint32_t ctrl = (((bt->brp        - 1) << 24) |
175                                  ((bt->sjw        - 1) << 22) |
176                                  ((bt->phase_seg1 - 1) << 19) |
177                                  ((bt->phase_seg2 - 1) << 16) |
178                                  ((bt->prop_seg   - 1) <<  0));
179
180                 printf("0x%08x", ctrl);
181         }
182 }
183
184 static void printf_btr_mcp251x(struct can_bittiming *bt, bool hdr)
185 {
186         uint8_t cnf1, cnf2, cnf3;
187
188         if (hdr) {
189                 printf("CNF1 CNF2 CNF3");
190         } else {
191                 cnf1 = ((bt->sjw - 1) << 6) | (bt->brp - 1);
192                 cnf2 = 0x80 | ((bt->phase_seg1 - 1) << 3) | (bt->prop_seg - 1);
193                 cnf3 = bt->phase_seg2 - 1;
194                 printf("0x%02x 0x%02x 0x%02x", cnf1, cnf2, cnf3);
195         }
196 }
197
198 static void printf_btr_ti_hecc(struct can_bittiming *bt, bool hdr)
199 {
200         if (hdr) {
201                 printf("%10s", "CANBTC");
202         } else {
203                 uint32_t can_btc;
204
205                 can_btc = (bt->phase_seg2 - 1) & 0x7;
206                 can_btc |= ((bt->phase_seg1 + bt->prop_seg - 1)
207                             & 0xF) << 3;
208                 can_btc |= ((bt->sjw - 1) & 0x3) << 8;
209                 can_btc |= ((bt->brp - 1) & 0xFF) << 16;
210
211                 printf("0x%08x", can_btc);
212         }
213 }
214
215 #define RCAR_CAN_BCR_TSEG1(x)   (((x) & 0x0f) << 20)
216 #define RCAR_CAN_BCR_BPR(x)     (((x) & 0x3ff) << 8)
217 #define RCAR_CAN_BCR_SJW(x)     (((x) & 0x3) << 4)
218 #define RCAR_CAN_BCR_TSEG2(x)   ((x) & 0x07)
219
220 static void printf_btr_rcar_can(struct can_bittiming *bt, bool hdr)
221 {
222         if (hdr) {
223                 printf("%10s", "CiBCR");
224         } else {
225                 uint32_t bcr;
226
227                 bcr = RCAR_CAN_BCR_TSEG1(bt->phase_seg1 + bt->prop_seg - 1) |
228                         RCAR_CAN_BCR_BPR(bt->brp - 1) |
229                         RCAR_CAN_BCR_SJW(bt->sjw - 1) |
230                         RCAR_CAN_BCR_TSEG2(bt->phase_seg2 - 1);
231
232                 printf("0x%08x", bcr << 8);
233         }
234 }
235
236 static struct calc_bittiming_const can_calc_consts[] = {
237         {
238                 .bittiming_const = {
239                         .name = "sja1000",
240                         .tseg1_min = 1,
241                         .tseg1_max = 16,
242                         .tseg2_min = 1,
243                         .tseg2_max = 8,
244                         .sjw_max = 4,
245                         .brp_min = 1,
246                         .brp_max = 64,
247                         .brp_inc = 1,
248                 },
249                 .ref_clk = 8000000,
250                 .printf_btr = printf_btr_sja1000,
251         }, {
252                 .bittiming_const = {
253                         .name = "mscan",
254                         .tseg1_min = 4,
255                         .tseg1_max = 16,
256                         .tseg2_min = 2,
257                         .tseg2_max = 8,
258                         .sjw_max = 4,
259                         .brp_min = 1,
260                         .brp_max = 64,
261                         .brp_inc = 1,
262                 },
263                 .ref_clk = 32000000,
264                 .printf_btr = printf_btr_sja1000,
265         }, {
266                 .bittiming_const = {
267                         .name = "mscan",
268                         .tseg1_min = 4,
269                         .tseg1_max = 16,
270                         .tseg2_min = 2,
271                         .tseg2_max = 8,
272                         .sjw_max = 4,
273                         .brp_min = 1,
274                         .brp_max = 64,
275                         .brp_inc = 1,
276                 },
277                 .ref_clk = 33000000,
278                 .printf_btr = printf_btr_sja1000,
279         }, {
280                 .bittiming_const = {
281                         .name = "mscan",
282                         .tseg1_min = 4,
283                         .tseg1_max = 16,
284                         .tseg2_min = 2,
285                         .tseg2_max = 8,
286                         .sjw_max = 4,
287                         .brp_min = 1,
288                         .brp_max = 64,
289                         .brp_inc = 1,
290                 },
291                 .ref_clk = 33300000,
292                 .printf_btr = printf_btr_sja1000,
293         }, {
294                 .bittiming_const = {
295                         .name = "mscan",
296                         .tseg1_min = 4,
297                         .tseg1_max = 16,
298                         .tseg2_min = 2,
299                         .tseg2_max = 8,
300                         .sjw_max = 4,
301                         .brp_min = 1,
302                         .brp_max = 64,
303                         .brp_inc = 1,
304                 },
305                 .ref_clk = 33333333,
306                 .printf_btr = printf_btr_sja1000,
307         }, {
308                 .bittiming_const = {
309                         .name = "mscan",
310                         .tseg1_min = 4,
311                         .tseg1_max = 16,
312                         .tseg2_min = 2,
313                         .tseg2_max = 8,
314                         .sjw_max = 4,
315                         .brp_min = 1,
316                         .brp_max = 64,
317                         .brp_inc = 1,
318                 },
319                 .ref_clk = 66660000,    /* mpc5121 */
320                 .printf_btr = printf_btr_sja1000,
321         }, {
322                 .bittiming_const = {
323                         .name = "mscan",
324                         .tseg1_min = 4,
325                         .tseg1_max = 16,
326                         .tseg2_min = 2,
327                         .tseg2_max = 8,
328                         .sjw_max = 4,
329                         .brp_min = 1,
330                         .brp_max = 64,
331                         .brp_inc = 1,
332                 },
333                 .ref_clk = 66666666,    /* mpc5121 */
334                 .printf_btr = printf_btr_sja1000,
335         }, {
336                 .bittiming_const = {
337                         .name = "at91",
338                         .tseg1_min = 4,
339                         .tseg1_max = 16,
340                         .tseg2_min = 2,
341                         .tseg2_max = 8,
342                         .sjw_max = 4,
343                         .brp_min = 2,
344                         .brp_max = 128,
345                         .brp_inc = 1,
346                 },
347                 .ref_clk = 100000000,
348                 .printf_btr = printf_btr_at91,
349         }, {
350                 .bittiming_const = {
351                         .name = "at91",
352                         .tseg1_min = 4,
353                         .tseg1_max = 16,
354                         .tseg2_min = 2,
355                         .tseg2_max = 8,
356                         .sjw_max = 4,
357                         .brp_min = 2,
358                         .brp_max = 128,
359                         .brp_inc = 1,
360                 },
361                 /* real world clock as found on the ronetix PM9263 */
362                 .ref_clk = 99532800,
363                 .printf_btr = printf_btr_at91,
364         }, {
365                 .bittiming_const = {
366                         .name = "flexcan",
367                         .tseg1_min = 4,
368                         .tseg1_max = 16,
369                         .tseg2_min = 2,
370                         .tseg2_max = 8,
371                         .sjw_max = 4,
372                         .brp_min = 1,
373                         .brp_max = 256,
374                         .brp_inc = 1,
375                 },
376                 .ref_clk = 24000000,    /* mx28 */
377                 .printf_btr = printf_btr_flexcan,
378         }, {
379                 .bittiming_const = {
380                         .name = "flexcan",
381                         .tseg1_min = 4,
382                         .tseg1_max = 16,
383                         .tseg2_min = 2,
384                         .tseg2_max = 8,
385                         .sjw_max = 4,
386                         .brp_min = 1,
387                         .brp_max = 256,
388                         .brp_inc = 1,
389                 },
390                 .ref_clk = 30000000,    /* mx6 */
391                 .printf_btr = printf_btr_flexcan,
392         }, {
393                 .bittiming_const = {
394                         .name = "flexcan",
395                         .tseg1_min = 4,
396                         .tseg1_max = 16,
397                         .tseg2_min = 2,
398                         .tseg2_max = 8,
399                         .sjw_max = 4,
400                         .brp_min = 1,
401                         .brp_max = 256,
402                         .brp_inc = 1,
403                 },
404                 .ref_clk = 49875000,
405                 .printf_btr = printf_btr_flexcan,
406         }, {
407                 .bittiming_const = {
408                         .name = "flexcan",
409                         .tseg1_min = 4,
410                         .tseg1_max = 16,
411                         .tseg2_min = 2,
412                         .tseg2_max = 8,
413                         .sjw_max = 4,
414                         .brp_min = 1,
415                         .brp_max = 256,
416                         .brp_inc = 1,
417                 },
418                 .ref_clk = 66000000,
419                 .printf_btr = printf_btr_flexcan,
420         }, {
421                 .bittiming_const = {
422                         .name = "flexcan",
423                         .tseg1_min = 4,
424                         .tseg1_max = 16,
425                         .tseg2_min = 2,
426                         .tseg2_max = 8,
427                         .sjw_max = 4,
428                         .brp_min = 1,
429                         .brp_max = 256,
430                         .brp_inc = 1,
431                 },
432                 .ref_clk = 66500000,
433                 .printf_btr = printf_btr_flexcan,
434         }, {
435                 .bittiming_const = {
436                         .name = "flexcan",
437                         .tseg1_min = 4,
438                         .tseg1_max = 16,
439                         .tseg2_min = 2,
440                         .tseg2_max = 8,
441                         .sjw_max = 4,
442                         .brp_min = 1,
443                         .brp_max = 256,
444                         .brp_inc = 1,
445                 },
446                 .ref_clk = 66666666,
447                 .printf_btr = printf_btr_flexcan,
448         }, {
449                 .bittiming_const = {
450                         .name = "flexcan",
451                         .tseg1_min = 4,
452                         .tseg1_max = 16,
453                         .tseg2_min = 2,
454                         .tseg2_max = 8,
455                         .sjw_max = 4,
456                         .brp_min = 1,
457                         .brp_max = 256,
458                         .brp_inc = 1,
459                 },
460                 .ref_clk = 83368421,
461                 .printf_btr = printf_btr_flexcan, /* vybrid */
462         }, {
463                 .bittiming_const = {
464                         .name = "mcp251x",
465                         .tseg1_min = 3,
466                         .tseg1_max = 16,
467                         .tseg2_min = 2,
468                         .tseg2_max = 8,
469                         .sjw_max = 4,
470                         .brp_min = 1,
471                         .brp_max = 64,
472                         .brp_inc = 1,
473                 },
474                 .ref_clk = 8000000,
475                 .printf_btr = printf_btr_mcp251x,
476         }, {
477                 .bittiming_const = {
478                         .name = "mcp251x",
479                         .tseg1_min = 3,
480                         .tseg1_max = 16,
481                         .tseg2_min = 2,
482                         .tseg2_max = 8,
483                         .sjw_max = 4,
484                         .brp_min = 1,
485                         .brp_max = 64,
486                         .brp_inc = 1,
487                 },
488                 .ref_clk = 16000000,
489                 .printf_btr = printf_btr_mcp251x,
490         }, {
491                 .bittiming_const = {
492                         .name = "ti_hecc",
493                         .tseg1_min = 1,
494                         .tseg1_max = 16,
495                         .tseg2_min = 1,
496                         .tseg2_max = 8,
497                         .sjw_max = 4,
498                         .brp_min = 1,
499                         .brp_max = 256,
500                         .brp_inc = 1,
501                 },
502                 .ref_clk = 13000000,
503                 .printf_btr = printf_btr_ti_hecc,
504         }, {
505                 .bittiming_const = {
506                         .name = "rcar_can",
507                         .tseg1_min = 4,
508                         .tseg1_max = 16,
509                         .tseg2_min = 2,
510                         .tseg2_max = 8,
511                         .sjw_max = 4,
512                         .brp_min = 1,
513                         .brp_max = 1024,
514                         .brp_inc = 1,
515                 },
516                 .ref_clk = 65000000,
517                 .printf_btr = printf_btr_rcar_can,
518         },
519 };
520
521 static long common_bitrates[] = {
522         1000000,
523         800000,
524         500000,
525         250000,
526         125000,
527         100000,
528         50000,
529         20000,
530         10000,
531 };
532
533 #define CAN_CALC_MAX_ERROR 50 /* in one-tenth of a percent */
534
535 static int can_update_spt(const struct can_bittiming_const *btc,
536                           int sampl_pt, int tseg, int *tseg1, int *tseg2)
537 {
538         *tseg2 = tseg + 1 - (sampl_pt * (tseg + 1)) / 1000;
539         if (*tseg2 < btc->tseg2_min)
540                 *tseg2 = btc->tseg2_min;
541         if (*tseg2 > btc->tseg2_max)
542                 *tseg2 = btc->tseg2_max;
543         *tseg1 = tseg - *tseg2;
544         if (*tseg1 > btc->tseg1_max) {
545                 *tseg1 = btc->tseg1_max;
546                 *tseg2 = tseg - *tseg1;
547         }
548         return 1000 * (tseg + 1 - *tseg2) / (tseg + 1);
549 }
550
551 static int can_calc_bittiming(struct net_device *dev, struct can_bittiming *bt)
552 {
553         struct can_priv *priv = netdev_priv(dev);
554         const struct can_bittiming_const *btc = priv->bittiming_const;
555         long rate = 0;
556         long best_error = 1000000000, error = 0;
557         int best_tseg = 0, best_brp = 0, brp = 0;
558         int tsegall, tseg = 0, tseg1 = 0, tseg2 = 0;
559         int spt_error = 1000, spt = 0, sampl_pt;
560         u64 v64;
561
562         if (!priv->bittiming_const)
563                 return -ENOTSUPP;
564
565         /* Use CIA recommended sample points */
566         if (bt->sample_point) {
567                 sampl_pt = bt->sample_point;
568         } else {
569                 if (bt->bitrate > 800000)
570                         sampl_pt = 750;
571                 else if (bt->bitrate > 500000)
572                         sampl_pt = 800;
573                 else
574                         sampl_pt = 875;
575         }
576
577         /* tseg even = round down, odd = round up */
578         for (tseg = (btc->tseg1_max + btc->tseg2_max) * 2 + 1;
579              tseg >= (btc->tseg1_min + btc->tseg2_min) * 2; tseg--) {
580                 tsegall = 1 + tseg / 2;
581                 /* Compute all possible tseg choices (tseg=tseg1+tseg2) */
582                 brp = priv->clock.freq / (tsegall * bt->bitrate) + tseg % 2;
583                 /* chose brp step which is possible in system */
584                 brp = (brp / btc->brp_inc) * btc->brp_inc;
585                 if ((brp < btc->brp_min) || (brp > btc->brp_max))
586                         continue;
587                 rate = priv->clock.freq / (brp * tsegall);
588                 error = bt->bitrate - rate;
589                 /* tseg brp biterror */
590                 if (error < 0)
591                         error = -error;
592                 if (error > best_error)
593                         continue;
594                 best_error = error;
595                 if (error == 0) {
596                         spt = can_update_spt(btc, sampl_pt, tseg / 2,
597                                              &tseg1, &tseg2);
598                         error = sampl_pt - spt;
599                         if (error < 0)
600                                 error = -error;
601                         if (error > spt_error)
602                                 continue;
603                         spt_error = error;
604                 }
605                 best_tseg = tseg / 2;
606                 best_brp = brp;
607                 if (error == 0)
608                         break;
609         }
610
611         if (best_error) {
612                 /* Error in one-tenth of a percent */
613                 error = (best_error * 1000) / bt->bitrate;
614                 if (error > CAN_CALC_MAX_ERROR) {
615                         dev_err(dev->dev.parent,
616                                 "bitrate error %ld.%ld%% too high\n",
617                                 error / 10, error % 10);
618                         return -EDOM;
619                 } else {
620                         dev_warn(dev->dev.parent, "bitrate error %ld.%ld%%\n",
621                                  error / 10, error % 10);
622                 }
623         }
624
625         /* real sample point */
626         bt->sample_point = can_update_spt(btc, sampl_pt, best_tseg,
627                                           &tseg1, &tseg2);
628
629         v64 = (u64)best_brp * 1000000000UL;
630         do_div(v64, priv->clock.freq);
631         bt->tq = (u32)v64;
632         bt->prop_seg = tseg1 / 2;
633         bt->phase_seg1 = tseg1 - bt->prop_seg;
634         bt->phase_seg2 = tseg2;
635         bt->sjw = 1;
636         bt->brp = best_brp;
637
638         /* real bit-rate */
639         bt->bitrate = priv->clock.freq / (bt->brp * (tseg1 + tseg2 + 1));
640
641         return 0;
642 }
643
644 static __u32 get_cia_sample_point(__u32 bitrate)
645 {
646         __u32 sampl_pt;
647
648         if (bitrate > 800000)
649                 sampl_pt = 750;
650         else if (bitrate > 500000)
651                 sampl_pt = 800;
652         else
653                 sampl_pt = 875;
654
655         return sampl_pt;
656 }
657
658 static void print_bit_timing(const struct calc_bittiming_const *btc,
659                              __u32 bitrate, __u32 sample_point, __u32 ref_clk,
660                              bool quiet)
661 {
662         struct net_device dev = {
663                 .priv.bittiming_const = &btc->bittiming_const,
664                 .priv.clock.freq = ref_clk,
665         };
666         struct can_bittiming bt = {
667                 .bitrate = bitrate,
668                 .sample_point = sample_point,
669         };
670         long rate_error, spt_error;
671
672         if (!quiet) {
673                 printf("Bit timing parameters for %s with %.6f MHz ref clock\n"
674                        "nominal                                 real Bitrt   nom  real SampP\n"
675                        "Bitrate TQ[ns] PrS PhS1 PhS2 SJW BRP Bitrate Error SampP SampP Error ",
676                        btc->bittiming_const.name,
677                        ref_clk / 1000000.0);
678
679                 btc->printf_btr(&bt, true);
680                 printf("\n");
681         }
682
683         if (can_calc_bittiming(&dev, &bt)) {
684                 printf("%7d ***bitrate not possible***\n", bitrate);
685                 return;
686         }
687
688         /* get nominal sample point */
689         if (!sample_point)
690                 sample_point = get_cia_sample_point(bitrate);
691
692         rate_error = abs((__s32)(bitrate - bt.bitrate));
693         spt_error = abs((__s32)(sample_point - bt.sample_point));
694
695         printf("%7d "
696                "%6d %3d %4d %4d "
697                "%3d %3d "
698                "%7d %4.1f%% "
699                "%4.1f%% %4.1f%% %4.1f%% ",
700                bitrate,
701                bt.tq, bt.prop_seg, bt.phase_seg1, bt.phase_seg2,
702                bt.sjw, bt.brp,
703
704                bt.bitrate,
705                100.0 * rate_error / bitrate,
706
707                sample_point / 10.0,
708                bt.sample_point / 10.0,
709                100.0 * spt_error / sample_point);
710
711         btc->printf_btr(&bt, false);
712         printf("\n");
713 }
714
715 static void do_list(void)
716 {
717         unsigned int i;
718
719         for (i = 0; i < ARRAY_SIZE(can_calc_consts); i++)
720                 printf("%s\n", can_calc_consts[i].bittiming_const.name);
721 }
722
723 int main(int argc, char *argv[])
724 {
725         __u32 bitrate = 0;
726         __u32 opt_ref_clk = 0, ref_clk;
727         int sampl_pt = 0;
728         bool quiet = false, list = false, found = false;
729         char *name = NULL;
730         unsigned int i, j;
731         int opt;
732
733         const struct calc_bittiming_const *btc = NULL;
734
735         while ((opt = getopt(argc, argv, "b:c:lps:")) != -1) {
736                 switch (opt) {
737                 case 'b':
738                         bitrate = atoi(optarg);
739                         break;
740
741                 case 'c':
742                         opt_ref_clk = atoi(optarg);
743                         break;
744
745                 case 'l':
746                         list = true;
747                         break;
748
749                 case 'q':
750                         quiet = true;
751                         break;
752
753                 case 's':
754                         sampl_pt = atoi(optarg);
755                         break;
756
757                 default:
758                         print_usage(argv[0]);
759                         break;
760                 }
761         }
762
763         if (argc > optind + 1)
764                 print_usage(argv[0]);
765
766         if (argc == optind + 1)
767                 name = argv[optind];
768
769         if (list) {
770                 do_list();
771                 exit(EXIT_SUCCESS);
772         }
773
774         if (sampl_pt && (sampl_pt >= 1000 || sampl_pt < 100))
775                 print_usage(argv[0]);
776
777         for (i = 0; i < ARRAY_SIZE(can_calc_consts); i++) {
778                 if (name && strcmp(can_calc_consts[i].bittiming_const.name, name))
779                         continue;
780
781                 found = true;
782                 btc = &can_calc_consts[i];
783
784                 if (opt_ref_clk)
785                         ref_clk = opt_ref_clk;
786                 else
787                         ref_clk = btc->ref_clk;
788
789                 if (bitrate) {
790                         print_bit_timing(btc, bitrate, sampl_pt, ref_clk, quiet);
791                 } else {
792                         for (j = 0; j < ARRAY_SIZE(common_bitrates); j++)
793                                 print_bit_timing(btc, common_bitrates[j],
794                                                  sampl_pt, ref_clk, j);
795                 }
796                 printf("\n");
797         }
798
799         if (!found) {
800                 printf("error: unknown CAN controller '%s', try one of these:\n\n", name);
801                 do_list();
802                 exit(EXIT_FAILURE);
803         }
804
805         exit(EXIT_SUCCESS);
806 }