forked from Imagelibrary/rtems
leon,can: introduce common CAN baud-rate calculation function
Reimplemented the baud-rate algorithm from scratch to cope with GRCAN, GRCANFD and OC_CAN devices. Update #4323.
This commit is contained in:
@@ -57,6 +57,7 @@ include_grlib_HEADERS += ../../bsps/include/grlib/apbuart_termios.h
|
|||||||
include_grlib_HEADERS += ../../bsps/include/grlib/b1553brm.h
|
include_grlib_HEADERS += ../../bsps/include/grlib/b1553brm.h
|
||||||
include_grlib_HEADERS += ../../bsps/include/grlib/b1553rt.h
|
include_grlib_HEADERS += ../../bsps/include/grlib/b1553rt.h
|
||||||
include_grlib_HEADERS += ../../bsps/include/grlib/bspcommon.h
|
include_grlib_HEADERS += ../../bsps/include/grlib/bspcommon.h
|
||||||
|
include_grlib_HEADERS += ../../bsps/include/grlib/canbtrs.h
|
||||||
include_grlib_HEADERS += ../../bsps/include/grlib/canmux.h
|
include_grlib_HEADERS += ../../bsps/include/grlib/canmux.h
|
||||||
include_grlib_HEADERS += ../../bsps/include/grlib/cons.h
|
include_grlib_HEADERS += ../../bsps/include/grlib/cons.h
|
||||||
include_grlib_HEADERS += ../../bsps/include/grlib/debug_defs.h
|
include_grlib_HEADERS += ../../bsps/include/grlib/debug_defs.h
|
||||||
|
|||||||
94
bsps/include/grlib/canbtrs.h
Normal file
94
bsps/include/grlib/canbtrs.h
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
/* SPDX-License-Identifier: BSD-2-Clause */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* @ingroup can
|
||||||
|
* @brief Common CAN baud-rate routines for OCCAN/GRCAN/GRCANFD controllers
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2019, 2020 Cobham Gaisler AB
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __GRLIB_CANBTRS_H__
|
||||||
|
#define __GRLIB_CANBTRS_H__
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup can CAN
|
||||||
|
*
|
||||||
|
* @ingroup RTEMSBSPsSharedGRLIB
|
||||||
|
*
|
||||||
|
* @brief CAN routines shared between OCCAN, GRCAN and GRCANFD controllers
|
||||||
|
*
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* CAN Baud-rate parameters, range of valid parameter values */
|
||||||
|
struct grlib_canbtrs_ranges {
|
||||||
|
unsigned int max_scaler;
|
||||||
|
char has_bpr;
|
||||||
|
unsigned char divfactor;
|
||||||
|
unsigned char min_tseg1;
|
||||||
|
unsigned char max_tseg1;
|
||||||
|
unsigned char min_tseg2;
|
||||||
|
unsigned char max_tseg2;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct grlib_canbtrs_timing {
|
||||||
|
unsigned char scaler;
|
||||||
|
unsigned char ps1;
|
||||||
|
unsigned char ps2;
|
||||||
|
unsigned char rsj;
|
||||||
|
unsigned char bpr;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* @brief Calculate CAN baud-rate generation parameters from requested baud-rate
|
||||||
|
*
|
||||||
|
* @param baud The CAN baud rate requested
|
||||||
|
* @param core_hz Input clock [Hz] to CAN core
|
||||||
|
* @param sampl_pt CAN sample point in %, 80 means 80%
|
||||||
|
* @param br CAN Baud-rate parameters limitations
|
||||||
|
* @param[out] timing result is placed here
|
||||||
|
*
|
||||||
|
* @retval 0 Baud-rate parameters sucessfully calculated
|
||||||
|
* @retval negative Failure to generate parameters with less than 5% error
|
||||||
|
* margin from requested baud-rate
|
||||||
|
*/
|
||||||
|
int grlib_canbtrs_calc_timing(
|
||||||
|
unsigned int baud,
|
||||||
|
unsigned int core_hz,
|
||||||
|
unsigned int sampl_pt,
|
||||||
|
struct grlib_canbtrs_ranges *br,
|
||||||
|
struct grlib_canbtrs_timing *timing
|
||||||
|
);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file
|
* @file
|
||||||
* @ingroup can
|
* @ingroup can
|
||||||
|
* @brief Driver API for the GRLIB GRCAN and GRCANFD controllers
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -25,6 +26,8 @@
|
|||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file
|
* @file
|
||||||
* @ingroup can
|
* @ingroup can
|
||||||
* @brief Gaisler wrapper to OpenCores CAN - driver interface
|
* @brief Driver API for GRLIB wrapper to OpenCores CAN
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/grlib/ascs/grascs.c
|
|||||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/grlib/btimer/gptimer.c
|
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/grlib/btimer/gptimer.c
|
||||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/grlib/btimer/tlib.c
|
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/grlib/btimer/tlib.c
|
||||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/grlib/btimer/tlib_ckinit.c
|
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/grlib/btimer/tlib_ckinit.c
|
||||||
|
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/grlib/can/canbtrs.c
|
||||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/grlib/can/canmux.c
|
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/grlib/can/canmux.c
|
||||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/grlib/can/grcan.c
|
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/grlib/can/grcan.c
|
||||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/grlib/can/occan.c
|
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/grlib/can/occan.c
|
||||||
|
|||||||
144
bsps/shared/grlib/can/canbtrs.c
Normal file
144
bsps/shared/grlib/can/canbtrs.c
Normal file
@@ -0,0 +1,144 @@
|
|||||||
|
/* SPDX-License-Identifier: BSD-2-Clause */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
*
|
||||||
|
* @ingroup can
|
||||||
|
*
|
||||||
|
* @brief Common CAN baud-rate routines for OCCAN/GRCAN/GRCANFD controllers
|
||||||
|
*
|
||||||
|
* Implements common routines for calculating CAN baud-rate parameters from
|
||||||
|
* a user provided baud-rate speed.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2019, 2020 Cobham Gailer AB
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <grlib/canbtrs.h>
|
||||||
|
|
||||||
|
/*#define GRLIB_CANBTRS_DEBUG*/
|
||||||
|
|
||||||
|
/* Calculate CAN baud-rate generation parameters from requested baud-rate */
|
||||||
|
int grlib_canbtrs_calc_timing(
|
||||||
|
unsigned int baud,
|
||||||
|
unsigned int core_hz,
|
||||||
|
unsigned int sampl_pt,
|
||||||
|
struct grlib_canbtrs_ranges *br,
|
||||||
|
struct grlib_canbtrs_timing *timing
|
||||||
|
)
|
||||||
|
{
|
||||||
|
int best_error = 2000000000, best_tseg=0, best_scaler=0;
|
||||||
|
int tseg=0, tseg1=0, tseg2=0, sc, tmp, error;
|
||||||
|
|
||||||
|
/* Default to 80% sample point */
|
||||||
|
if ((sampl_pt < 50) || (sampl_pt > 99))
|
||||||
|
sampl_pt = 80;
|
||||||
|
|
||||||
|
/* step though all TSEG1+TSEG2 values possible */
|
||||||
|
for (tseg = (br->min_tseg1 + br->min_tseg2);
|
||||||
|
tseg <= (br->max_tseg1 + br->max_tseg2);
|
||||||
|
tseg++) {
|
||||||
|
/* calculate scaler */
|
||||||
|
tmp = ((br->divfactor + tseg) * baud);
|
||||||
|
sc = (core_hz * 2)/ tmp - core_hz / tmp;
|
||||||
|
if (sc <= 0 || sc > br->max_scaler)
|
||||||
|
continue;
|
||||||
|
if (br->has_bpr &&
|
||||||
|
(((sc > 256 * 1) && (sc <= 256 * 2) && (sc & 0x1)) ||
|
||||||
|
((sc > 256 * 2) && (sc <= 256 * 4) && (sc & 0x3)) ||
|
||||||
|
((sc > 256 * 4) && (sc <= 256 * 8) && (sc & 0x7))))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
error = baud - core_hz / (sc * (br->divfactor + tseg));
|
||||||
|
#ifdef GRLIB_CANBTRS_DEBUG
|
||||||
|
printf(" baud=%d, tseg=%d, sc=%d, error=%d\n",
|
||||||
|
baud, tseg, sc, error);
|
||||||
|
#endif
|
||||||
|
if (error < 0)
|
||||||
|
error = -error;
|
||||||
|
|
||||||
|
/* tseg is increasing, so we accept higher tseg with the same
|
||||||
|
* baudrate to get better sampling point.
|
||||||
|
*/
|
||||||
|
if (error <= best_error) {
|
||||||
|
best_error = error;
|
||||||
|
best_tseg = tseg;
|
||||||
|
best_scaler = sc;
|
||||||
|
#ifdef GRLIB_CANBTRS_DEBUG
|
||||||
|
printf(" ! best baud=%d\n",
|
||||||
|
core_hz/(sc * (br->divfactor + tseg)));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* return an error if 5% off baud-rate */
|
||||||
|
if (best_error && (baud / best_error <= 5)) {
|
||||||
|
return -2;
|
||||||
|
} else if (!timing) {
|
||||||
|
return 0; /* nothing to store result in, but a valid bitrate can be calculated */
|
||||||
|
}
|
||||||
|
|
||||||
|
tseg2 = (best_tseg + br->divfactor) -
|
||||||
|
((sampl_pt * (best_tseg + br->divfactor)) / 100);
|
||||||
|
if (tseg2 < br->min_tseg2) {
|
||||||
|
tseg2 = br->min_tseg2;
|
||||||
|
} else if (tseg2 > br->max_tseg2) {
|
||||||
|
tseg2 = br->max_tseg2;
|
||||||
|
}
|
||||||
|
|
||||||
|
tseg1 = best_tseg - tseg2;
|
||||||
|
if (tseg1 > br->max_tseg1) {
|
||||||
|
tseg1 = br->max_tseg1;
|
||||||
|
tseg2 = best_tseg - tseg1;
|
||||||
|
} else if (tseg1 < br->min_tseg1) {
|
||||||
|
tseg1 = br->min_tseg1;
|
||||||
|
tseg2 = best_tseg - tseg1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get scaler and BPR from pseudo SCALER clock */
|
||||||
|
if (best_scaler <= 256) {
|
||||||
|
timing->scaler = best_scaler - 1;
|
||||||
|
timing->bpr = 0;
|
||||||
|
} else if (best_scaler <= 256 * 2) {
|
||||||
|
timing->scaler = ((best_scaler + 1) >> 1) - 1;
|
||||||
|
timing->bpr = 1;
|
||||||
|
} else if (best_scaler <= 256 * 4) {
|
||||||
|
timing->scaler = ((best_scaler + 1) >> 2) - 1;
|
||||||
|
timing->bpr = 2;
|
||||||
|
} else {
|
||||||
|
timing->scaler = ((best_scaler + 1) >> 3) - 1;
|
||||||
|
timing->bpr = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
timing->ps1 = tseg1;
|
||||||
|
timing->ps2 = tseg2;
|
||||||
|
timing->rsj = 1;
|
||||||
|
|
||||||
|
#ifdef GRLIB_CANBTRS_DEBUG
|
||||||
|
printf(" ! result: sc=%d,bpr=%d,ps1=%d,ps2=%d\n", timing->scaler, timing->bpr, timing->ps1, timing->ps2);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -21,6 +21,7 @@ install:
|
|||||||
- bsps/include/grlib/b1553brm.h
|
- bsps/include/grlib/b1553brm.h
|
||||||
- bsps/include/grlib/b1553rt.h
|
- bsps/include/grlib/b1553rt.h
|
||||||
- bsps/include/grlib/bspcommon.h
|
- bsps/include/grlib/bspcommon.h
|
||||||
|
- bsps/include/grlib/canbtrs.h
|
||||||
- bsps/include/grlib/canmux.h
|
- bsps/include/grlib/canmux.h
|
||||||
- bsps/include/grlib/cons.h
|
- bsps/include/grlib/cons.h
|
||||||
- bsps/include/grlib/debug_defs.h
|
- bsps/include/grlib/debug_defs.h
|
||||||
@@ -99,6 +100,7 @@ source:
|
|||||||
- bsps/shared/grlib/btimer/gptimer.c
|
- bsps/shared/grlib/btimer/gptimer.c
|
||||||
- bsps/shared/grlib/btimer/tlib.c
|
- bsps/shared/grlib/btimer/tlib.c
|
||||||
- bsps/shared/grlib/btimer/tlib_ckinit.c
|
- bsps/shared/grlib/btimer/tlib_ckinit.c
|
||||||
|
- bsps/shared/grlib/can/canbtrs.c
|
||||||
- bsps/shared/grlib/can/canmux.c
|
- bsps/shared/grlib/can/canmux.c
|
||||||
- bsps/shared/grlib/can/grcan.c
|
- bsps/shared/grlib/can/grcan.c
|
||||||
- bsps/shared/grlib/can/occan.c
|
- bsps/shared/grlib/can/occan.c
|
||||||
|
|||||||
Reference in New Issue
Block a user