File indexing completed on 2025-05-11 08:24:06
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039 #include <grlib/canbtrs.h>
0040
0041
0042
0043
0044 int grlib_canbtrs_calc_timing(
0045 unsigned int baud,
0046 unsigned int core_hz,
0047 unsigned int sampl_pt,
0048 struct grlib_canbtrs_ranges *br,
0049 struct grlib_canbtrs_timing *timing
0050 )
0051 {
0052 int best_error = 2000000000, best_tseg=0, best_scaler=0;
0053 int tseg=0, tseg1=0, tseg2=0, sc, tmp, error;
0054
0055
0056 if ((sampl_pt < 50) || (sampl_pt > 99))
0057 sampl_pt = 80;
0058
0059
0060 for (tseg = (br->min_tseg1 + br->min_tseg2);
0061 tseg <= (br->max_tseg1 + br->max_tseg2);
0062 tseg++) {
0063
0064 tmp = ((br->divfactor + tseg) * baud);
0065 sc = (core_hz * 2)/ tmp - core_hz / tmp;
0066 if (sc <= 0 || sc > br->max_scaler)
0067 continue;
0068 if (br->has_bpr &&
0069 (((sc > 256 * 1) && (sc <= 256 * 2) && (sc & 0x1)) ||
0070 ((sc > 256 * 2) && (sc <= 256 * 4) && (sc & 0x3)) ||
0071 ((sc > 256 * 4) && (sc <= 256 * 8) && (sc & 0x7))))
0072 continue;
0073
0074 error = baud - core_hz / (sc * (br->divfactor + tseg));
0075 #ifdef GRLIB_CANBTRS_DEBUG
0076 printf(" baud=%d, tseg=%d, sc=%d, error=%d\n",
0077 baud, tseg, sc, error);
0078 #endif
0079 if (error < 0)
0080 error = -error;
0081
0082
0083
0084
0085 if (error <= best_error) {
0086 best_error = error;
0087 best_tseg = tseg;
0088 best_scaler = sc;
0089 #ifdef GRLIB_CANBTRS_DEBUG
0090 printf(" ! best baud=%d\n",
0091 core_hz/(sc * (br->divfactor + tseg)));
0092 #endif
0093 }
0094 }
0095
0096
0097 if (best_error && (baud / best_error <= 5)) {
0098 return -2;
0099 } else if (!timing) {
0100 return 0;
0101 }
0102
0103 tseg2 = (best_tseg + br->divfactor) -
0104 ((sampl_pt * (best_tseg + br->divfactor)) / 100);
0105 if (tseg2 < br->min_tseg2) {
0106 tseg2 = br->min_tseg2;
0107 } else if (tseg2 > br->max_tseg2) {
0108 tseg2 = br->max_tseg2;
0109 }
0110
0111 tseg1 = best_tseg - tseg2;
0112 if (tseg1 > br->max_tseg1) {
0113 tseg1 = br->max_tseg1;
0114 tseg2 = best_tseg - tseg1;
0115 } else if (tseg1 < br->min_tseg1) {
0116 tseg1 = br->min_tseg1;
0117 tseg2 = best_tseg - tseg1;
0118 }
0119
0120
0121 if (best_scaler <= 256) {
0122 timing->scaler = best_scaler - 1;
0123 timing->bpr = 0;
0124 } else if (best_scaler <= 256 * 2) {
0125 timing->scaler = ((best_scaler + 1) >> 1) - 1;
0126 timing->bpr = 1;
0127 } else if (best_scaler <= 256 * 4) {
0128 timing->scaler = ((best_scaler + 1) >> 2) - 1;
0129 timing->bpr = 2;
0130 } else {
0131 timing->scaler = ((best_scaler + 1) >> 3) - 1;
0132 timing->bpr = 3;
0133 }
0134
0135 timing->ps1 = tseg1;
0136 timing->ps2 = tseg2;
0137 timing->rsj = 1;
0138
0139 #ifdef GRLIB_CANBTRS_DEBUG
0140 printf(" ! result: sc=%d,bpr=%d,ps1=%d,ps2=%d\n", timing->scaler, timing->bpr, timing->ps1, timing->ps2);
0141 #endif
0142
0143 return 0;
0144 }