<div dir="auto"><div><br><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri, Oct 16, 2020, 6:50 AM Daniel Hellstrom <<a href="mailto:daniel@gaisler.com">daniel@gaisler.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Reimplemented the baud-rate algorithm from scratch to cope with<br>
GRCAN, GRCANFD and OC_CAN devices.<br>
---<br>
 bsps/<a href="http://headers.am" rel="noreferrer noreferrer" target="_blank">headers.am</a>                 |   1 +<br>
 bsps/include/grlib/canbtrs.h    |  80 ++++++++++++++++++++++<br>
 bsps/shared/<a href="http://grlib-sources.am" rel="noreferrer noreferrer" target="_blank">grlib-sources.am</a>    |   1 +<br>
 bsps/shared/grlib/can/canbtrs.c | 143 ++++++++++++++++++++++++++++++++++++++++<br>
 4 files changed, 225 insertions(+)<br>
 create mode 100644 bsps/include/grlib/canbtrs.h<br>
 create mode 100644 bsps/shared/grlib/can/canbtrs.c<br>
<br>
diff --git a/bsps/<a href="http://headers.am" rel="noreferrer noreferrer" target="_blank">headers.am</a> b/bsps/<a href="http://headers.am" rel="noreferrer noreferrer" target="_blank">headers.am</a><br>
index 5af7e43..2c9b31d 100644<br>
--- a/bsps/<a href="http://headers.am" rel="noreferrer noreferrer" target="_blank">headers.am</a><br>
+++ b/bsps/<a href="http://headers.am" rel="noreferrer noreferrer" target="_blank">headers.am</a><br>
@@ -34,6 +34,7 @@ include_grlib_HEADERS += ../../bsps/include/grlib/apbuart_termios.h<br>
 include_grlib_HEADERS += ../../bsps/include/grlib/b1553brm.h<br>
 include_grlib_HEADERS += ../../bsps/include/grlib/b1553rt.h<br>
 include_grlib_HEADERS += ../../bsps/include/grlib/bspcommon.h<br>
+include_grlib_HEADERS += ../../bsps/include/grlib/canbtrs.h<br>
 include_grlib_HEADERS += ../../bsps/include/grlib/canmux.h<br>
 include_grlib_HEADERS += ../../bsps/include/grlib/cons.h<br>
 include_grlib_HEADERS += ../../bsps/include/grlib/debug_defs.h<br>
diff --git a/bsps/include/grlib/canbtrs.h b/bsps/include/grlib/canbtrs.h<br>
new file mode 100644<br>
index 0000000..3b2118b<br>
--- /dev/null<br>
+++ b/bsps/include/grlib/canbtrs.h<br>
@@ -0,0 +1,80 @@<br>
+/* SPDX-License-Identifier: BSD-2-Clause */<br>
+<br>
+/**<br>
+ * @file<br>
+ * @ingroup can<br>
+ * @brief Common CAN baud-rate routines for OCCAN/GRCAN/GRCANFD controllers<br>
+ */<br>
+<br>
+/*<br>
+ * Copyright (C) 2019, 2020 Cobham Gaisler AB<br>
+ *<br>
+ * Redistribution and use in source and binary forms, with or without<br>
+ * modification, are permitted provided that the following conditions<br>
+ * are met:<br>
+ * 1. Redistributions of source code must retain the above copyright<br>
+ *    notice, this list of conditions and the following disclaimer.<br>
+ * 2. Redistributions in binary form must reproduce the above copyright<br>
+ *    notice, this list of conditions and the following disclaimer in the<br>
+ *    documentation and/or other materials provided with the distribution.<br>
+ *<br>
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"<br>
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE<br>
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE<br>
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE<br>
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR<br>
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF<br>
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS<br>
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN<br>
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)<br>
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE<br>
+ * POSSIBILITY OF SUCH DAMAGE.<br>
+ */<br>
+<br>
+#ifndef __GRLIB_CANBTRS_H__<br>
+#define __GRLIB_CANBTRS_H__<br>
+<br>
+#ifdef __cplusplus<br>
+extern "C" {<br>
+#endif<br>
+<br>
+/* CAN Baud-rate parameters, range of valid parameter values */<br>
+struct grlib_canbtrs_ranges {<br>
+       unsigned int max_scaler;<br>
+       char has_bpr;<br>
+       unsigned char divfactor;<br>
+       unsigned char min_tseg1;<br>
+       unsigned char max_tseg1;<br>
+       unsigned char min_tseg2;<br>
+       unsigned char max_tseg2;<br>
+};<br>
+<br>
+struct grlib_canbtrs_timing {<br>
+       unsigned char scaler;<br>
+       unsigned char ps1;<br>
+       unsigned char ps2;<br>
+       unsigned char rsj;<br>
+       unsigned char bpr;<br>
+};<br>
+<br>
+/* Calculate CAN baud-rate generation parameters from requested baud-rate<br>
+ *<br>
+ * \param baud       The CAN baud rate requested<br>
+ * \param core_hz    Input clock [Hz] to CAN core<br>
+ * \param sampl_pt   CAN sample point in %, 80 means 80%<br>
+ * \param br         CAN Baud-rate parameters limitations<br>
+ * \param timing     result is placed here<br>
+ */<br></blockquote></div></div><div dir="auto"><br></div><div dir="auto">I thought we used @ notation for Doxygen not leading backslash in front of commands.</div><div dir="auto"><br></div><div dir="auto"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+int grlib_canbtrs_calc_timing(<br>
+       unsigned int baud,<br>
+       unsigned int core_hz,<br>
+       unsigned int sampl_pt,<br>
+       struct grlib_canbtrs_ranges *br,<br>
+       struct grlib_canbtrs_timing *timing<br>
+       );<br>
+<br>
+#ifdef __cplusplus<br>
+}<br>
+#endif<br>
+<br>
+#endif<br>
diff --git a/bsps/shared/<a href="http://grlib-sources.am" rel="noreferrer noreferrer" target="_blank">grlib-sources.am</a> b/bsps/shared/<a href="http://grlib-sources.am" rel="noreferrer noreferrer" target="_blank">grlib-sources.am</a><br>
index 512a48c..f2ad1bf 100644<br>
--- a/bsps/shared/<a href="http://grlib-sources.am" rel="noreferrer noreferrer" target="_blank">grlib-sources.am</a><br>
+++ b/bsps/shared/<a href="http://grlib-sources.am" rel="noreferrer noreferrer" target="_blank">grlib-sources.am</a><br>
@@ -20,6 +20,7 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/grlib/ascs/grascs.c<br>
 librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/grlib/btimer/gptimer.c<br>
 librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/grlib/btimer/tlib.c<br>
 librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/grlib/btimer/tlib_ckinit.c<br>
+librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/grlib/can/canbtrs.c<br>
 librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/grlib/can/canmux.c<br>
 librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/grlib/can/grcan.c<br>
 librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/grlib/can/occan.c<br>
diff --git a/bsps/shared/grlib/can/canbtrs.c b/bsps/shared/grlib/can/canbtrs.c<br>
new file mode 100644<br>
index 0000000..d28efbc<br>
--- /dev/null<br>
+++ b/bsps/shared/grlib/can/canbtrs.c<br>
@@ -0,0 +1,143 @@<br>
+/* SPDX-License-Identifier: BSD-2-Clause */<br>
+<br>
+/**<br>
+ * @file<br>
+ *<br>
+ * @ingroup can<br>
+ *<br>
+ * @brief Common CAN baud-rate routines for OCCAN/GRCAN/GRCANFD controllers<br>
+ *<br>
+ * Implements common routines for calculating CAN baud-rate parameters from<br>
+ * a user provided baud-rate speed.<br>
+ */<br>
+<br>
+/*<br>
+ * Copyright (C) 2019, 2020 Cobham Gailer AB<br>
+ *<br>
+ * Redistribution and use in source and binary forms, with or without<br>
+ * modification, are permitted provided that the following conditions<br>
+ * are met:<br>
+ * 1. Redistributions of source code must retain the above copyright<br>
+ *    notice, this list of conditions and the following disclaimer.<br>
+ * 2. Redistributions in binary form must reproduce the above copyright<br>
+ *    notice, this list of conditions and the following disclaimer in the<br>
+ *    documentation and/or other materials provided with the distribution.<br>
+ *<br>
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"<br>
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE<br>
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE<br>
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE<br>
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR<br>
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF<br>
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS<br>
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN<br>
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)<br>
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE<br>
+ * POSSIBILITY OF SUCH DAMAGE.<br>
+ */<br>
+<br>
+#include <grlib/canbtrs.h><br>
+<br>
+/*#define GRLIB_CANBTRS_DEBUG*/<br>
+<br>
+/* Calculate CAN baud-rate generation parameters from requested baud-rate */<br>
+int grlib_canbtrs_calc_timing(<br>
+       unsigned int baud,<br>
+       unsigned int core_hz,<br>
+       unsigned int sampl_pt,<br>
+       struct grlib_canbtrs_ranges *br,<br>
+       struct grlib_canbtrs_timing *timing<br>
+       )<br>
+{<br>
+       int best_error = 2000000000, best_tseg=0, best_scaler=0;<br>
+       int tseg=0, tseg1=0, tseg2=0, sc, error;<br>
+<br>
+       /* Default to 80% sample point */<br>
+       if ((sampl_pt < 50) || (sampl_pt > 99))<br>
+               sampl_pt = 80;<br>
+<br>
+       /* step though all TSEG1+TSEG2 values possible */<br>
+       for (tseg = (br->min_tseg1 + br->min_tseg2);<br>
+            tseg <= (br->max_tseg1 + br->max_tseg2);<br>
+            tseg++) {<br>
+               /* calculate scaler */<br>
+               sc = core_hz / ((br->divfactor + tseg) * baud);<br>
+               if (sc <= 0 || sc > br->max_scaler)<br>
+                       continue;<br>
+               if (br->has_bpr &&<br>
+                   (((sc > 256 * 1) && (sc <= 256 * 2) && (sc & 0x1)) ||<br>
+                   ((sc > 256 * 2) && (sc <= 256 * 4) && (sc & 0x3)) ||<br>
+                   ((sc > 256 * 4) && (sc <= 256 * 8) && (sc & 0x7))))<br>
+                       continue;<br>
+<br>
+               error = baud - core_hz / (sc * (br->divfactor + tseg));<br>
+#ifdef GRLIB_CANBTRS_DEBUG<br>
+               printf("  baud=%d, tseg=%d, sc=%d, error=%d\n",<br>
+                      baud, tseg, sc, error);<br>
+#endif<br>
+               if (error < 0)<br>
+                       error = -error;<br>
+<br>
+               /* tseg is increasing, so we accept higher tseg with the same<br>
+                * baudrate to get better sampling point.<br>
+                */<br>
+               if (error <= best_error) {<br>
+                       best_error = error;<br>
+                       best_tseg = tseg;<br>
+                       best_scaler = sc;<br>
+#ifdef GRLIB_CANBTRS_DEBUG<br>
+                       printf("  ! best baud=%d\n",<br>
+                              core_hz/(sc * (br->divfactor + tseg)));<br>
+#endif<br>
+               }<br>
+       }<br>
+<br>
+       /* return an error if 5% off baud-rate */<br>
+       if (best_error && (baud / best_error <= 5)) {<br>
+               return -2;<br>
+       } else if (!timing) {<br>
+               return 0; /* nothing to store result in, but a valid bitrate can be calculated */<br>
+       }<br>
+<br>
+       tseg2 = (best_tseg + br->divfactor) -<br>
+               ((sampl_pt * (best_tseg + br->divfactor)) / 100);<br>
+       if (tseg2 < br->min_tseg2) {<br>
+               tseg2 = br->min_tseg2;<br>
+       } else if (tseg2 > br->max_tseg2) {<br>
+               tseg2 = br->max_tseg2;<br>
+       }<br>
+<br>
+       tseg1 = best_tseg - tseg2;<br>
+       if (tseg1 > br->max_tseg1) {<br>
+               tseg1 = br->max_tseg1;<br>
+               tseg2 = best_tseg - tseg1;<br>
+       } else if (tseg1 < br->min_tseg1) {<br>
+               tseg1 = br->min_tseg1;<br>
+               tseg2 = best_tseg - tseg1;<br>
+       }<br>
+<br>
+       /* Get scaler and BPR from pseudo SCALER clock */<br>
+       if (best_scaler <= 256) {<br>
+               timing->scaler = best_scaler - 1;<br>
+               timing->bpr = 0;<br>
+       } else if (best_scaler <= 256 * 2) {<br>
+               timing->scaler = ((best_scaler + 1) >> 1) - 1;<br>
+               timing->bpr = 1;<br>
+       } else if (best_scaler <= 256 * 4) {<br>
+               timing->scaler = ((best_scaler + 1) >> 2) - 1;<br>
+               timing->bpr = 2;<br>
+       } else {<br>
+               timing->scaler = ((best_scaler + 1) >> 3) - 1;<br>
+               timing->bpr = 3;<br>
+       }<br>
+<br>
+       timing->ps1    = tseg1;<br>
+       timing->ps2    = tseg2;<br>
+       timing->rsj    = 1;<br>
+<br>
+#ifdef GRLIB_CANBTRS_DEBUG<br>
+       printf("  ! result: sc=%d,bpr=%d,ps1=%d,ps2=%d\n", timing->scaler, timing->bpr, timing->ps1, timing->ps2);<br>
+#endif<br>
+<br>
+       return 0;<br>
+}<br>
-- <br>
2.7.4<br>
<br>
_______________________________________________<br>
devel mailing list<br>
<a href="mailto:devel@rtems.org" target="_blank" rel="noreferrer">devel@rtems.org</a><br>
<a href="http://lists.rtems.org/mailman/listinfo/devel" rel="noreferrer noreferrer" target="_blank">http://lists.rtems.org/mailman/listinfo/devel</a><br>
</blockquote></div></div></div>