Skip to content

Commit e9135f5

Browse files
committed
Fixing CAN for good, wrong CLOCK selected for CANCLK within Santiago (garbage in, garbage out).
1 parent eb10703 commit e9135f5

File tree

5 files changed

+81
-83
lines changed

5 files changed

+81
-83
lines changed

libraries/CAN/extras/test/src/test_calc_can_bit_timinig.cpp

Lines changed: 38 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -24,72 +24,78 @@ SCENARIO("calc_can_bit_timing", "[calc_can_bit_timing]")
2424
{
2525
GIVEN("Santiago")
2626
{
27-
static uint32_t const F_CAN_CLK_Hz = 20*1000*1000UL;
28-
static uint32_t const TQ_MIN = 8;
29-
static uint32_t const TQ_MAX = 25;
30-
static uint32_t const SYNC_JUMP_WIDTH = 4;
27+
static uint32_t const F_CAN_CLK_Hz = 24*1000*1000UL;
28+
static uint32_t const TQ_MIN = 8;
29+
static uint32_t const TQ_MAX = 25;
30+
static uint32_t const TSEG_1_MIN = 4;
31+
static uint32_t const TSEG_1_MAX = 16;
32+
static uint32_t const TSEG_2_MIN = 2;
33+
static uint32_t const TSEG_2_MAX = 8;
3134

3235
WHEN("CanBitRate::BR_125k")
3336
{
3437
auto [is_valid_baudrate, baud_rate_prescaler, time_segment_1, time_segment_2] =
35-
util::calc_can_bit_timing(CanBitRate::BR_125k, F_CAN_CLK_Hz, TQ_MIN, TQ_MAX, SYNC_JUMP_WIDTH);
38+
util::calc_can_bit_timing(CanBitRate::BR_125k, F_CAN_CLK_Hz, TQ_MIN, TQ_MAX, TSEG_1_MIN, TSEG_1_MAX, TSEG_2_MIN, TSEG_2_MAX);
3639
THEN("")
3740
{
38-
REQUIRE(is_valid_baudrate == true);
39-
REQUIRE(baud_rate_prescaler == 8);
40-
REQUIRE(time_segment_1 == 11);
41-
REQUIRE(time_segment_2 == 4);
41+
REQUIRE(is_valid_baudrate == true);
42+
REQUIRE(baud_rate_prescaler == 12);
43+
REQUIRE(time_segment_1 == 11);
44+
REQUIRE(time_segment_2 == 4);
4245
}
4346
}
4447
WHEN("CanBitRate::BR_250k")
4548
{
4649
auto [is_valid_baudrate, baud_rate_prescaler, time_segment_1, time_segment_2] =
47-
util::calc_can_bit_timing(CanBitRate::BR_250k, F_CAN_CLK_Hz, TQ_MIN, TQ_MAX, SYNC_JUMP_WIDTH);
50+
util::calc_can_bit_timing(CanBitRate::BR_250k, F_CAN_CLK_Hz, TQ_MIN, TQ_MAX, TSEG_1_MIN, TSEG_1_MAX, TSEG_2_MIN, TSEG_2_MAX);
4851
THEN("")
4952
{
50-
REQUIRE(is_valid_baudrate == true);
51-
REQUIRE(baud_rate_prescaler == 4);
52-
REQUIRE(time_segment_1 == 11);
53-
REQUIRE(time_segment_2 == 4);
53+
REQUIRE(is_valid_baudrate == true);
54+
REQUIRE(baud_rate_prescaler == 6);
55+
REQUIRE(time_segment_1 == 11);
56+
REQUIRE(time_segment_2 == 4);
5457
}
5558
}
5659
WHEN("CanBitRate::BR_500k")
5760
{
5861
auto [is_valid_baudrate, baud_rate_prescaler, time_segment_1, time_segment_2] =
59-
util::calc_can_bit_timing(CanBitRate::BR_500k, F_CAN_CLK_Hz, TQ_MIN, TQ_MAX, SYNC_JUMP_WIDTH);
62+
util::calc_can_bit_timing(CanBitRate::BR_500k, F_CAN_CLK_Hz, TQ_MIN, TQ_MAX, TSEG_1_MIN, TSEG_1_MAX, TSEG_2_MIN, TSEG_2_MAX);
6063
THEN("")
6164
{
62-
REQUIRE(is_valid_baudrate == true);
63-
REQUIRE(baud_rate_prescaler == 2);
64-
REQUIRE(time_segment_1 == 11);
65-
REQUIRE(time_segment_2 == 4);
65+
REQUIRE(is_valid_baudrate == true);
66+
REQUIRE(baud_rate_prescaler == 3);
67+
REQUIRE(time_segment_1 == 11);
68+
REQUIRE(time_segment_2 == 4);
6669
}
6770
}
6871
WHEN("CanBitRate::BR_1000k")
6972
{
7073
auto [is_valid_baudrate, baud_rate_prescaler, time_segment_1, time_segment_2] =
71-
util::calc_can_bit_timing(CanBitRate::BR_1000k, F_CAN_CLK_Hz, TQ_MIN, TQ_MAX, SYNC_JUMP_WIDTH);
74+
util::calc_can_bit_timing(CanBitRate::BR_1000k, F_CAN_CLK_Hz, TQ_MIN, TQ_MAX, TSEG_1_MIN, TSEG_1_MAX, TSEG_2_MIN, TSEG_2_MAX);
7275
THEN("")
7376
{
74-
REQUIRE(is_valid_baudrate == true);
75-
REQUIRE(baud_rate_prescaler == 1);
76-
REQUIRE(time_segment_1 == 11);
77-
REQUIRE(time_segment_2 == 4);
77+
REQUIRE(is_valid_baudrate == true);
78+
REQUIRE(baud_rate_prescaler == 2);
79+
REQUIRE(time_segment_1 == 8);
80+
REQUIRE(time_segment_2 == 3);
7881
}
7982
}
8083
}
8184

8285
GIVEN("Portenta H33")
8386
{
8487
static uint32_t const F_CAN_CLK_Hz = 24*1000*1000UL;
85-
static uint32_t const TQ_MIN = 5;
86-
static uint32_t const TQ_MAX = 49;
87-
static uint32_t const SYNC_JUMP_WIDTH = 1;
88+
static uint32_t const TQ_MIN = 5;
89+
static uint32_t const TQ_MAX = 49;
90+
static uint32_t const TSEG_1_MIN = 2;
91+
static uint32_t const TSEG_1_MAX = 39;
92+
static uint32_t const TSEG_2_MIN = 2;
93+
static uint32_t const TSEG_2_MAX = 10;
8894

8995
WHEN("CanBitRate::BR_125k")
9096
{
9197
auto [is_valid_baudrate, baud_rate_prescaler, time_segment_1, time_segment_2] =
92-
util::calc_can_bit_timing(CanBitRate::BR_125k, F_CAN_CLK_Hz, TQ_MIN, TQ_MAX, SYNC_JUMP_WIDTH);
98+
util::calc_can_bit_timing(CanBitRate::BR_125k, F_CAN_CLK_Hz, TQ_MIN, TQ_MAX, TSEG_1_MIN, TSEG_1_MAX, TSEG_2_MIN, TSEG_2_MAX);
9399
THEN("")
94100
{
95101
REQUIRE(is_valid_baudrate == true);
@@ -101,19 +107,19 @@ SCENARIO("calc_can_bit_timing", "[calc_can_bit_timing]")
101107
WHEN("CanBitRate::BR_250k")
102108
{
103109
auto [is_valid_baudrate, baud_rate_prescaler, time_segment_1, time_segment_2] =
104-
util::calc_can_bit_timing(CanBitRate::BR_250k, F_CAN_CLK_Hz, TQ_MIN, TQ_MAX, SYNC_JUMP_WIDTH);
110+
util::calc_can_bit_timing(CanBitRate::BR_250k, F_CAN_CLK_Hz, TQ_MIN, TQ_MAX, TSEG_1_MIN, TSEG_1_MAX, TSEG_2_MIN, TSEG_2_MAX);
105111
THEN("")
106112
{
107113
REQUIRE(is_valid_baudrate == true);
108114
REQUIRE(baud_rate_prescaler == 3);
109-
REQUIRE(time_segment_1 == 28);
115+
REQUIRE(time_segment_1 == 23);
110116
REQUIRE(time_segment_2 == 8);
111117
}
112118
}
113119
WHEN("CanBitRate::BR_500k")
114120
{
115121
auto [is_valid_baudrate, baud_rate_prescaler, time_segment_1, time_segment_2] =
116-
util::calc_can_bit_timing(CanBitRate::BR_500k, F_CAN_CLK_Hz, TQ_MIN, TQ_MAX, SYNC_JUMP_WIDTH);
122+
util::calc_can_bit_timing(CanBitRate::BR_500k, F_CAN_CLK_Hz, TQ_MIN, TQ_MAX, TSEG_1_MIN, TSEG_1_MAX, TSEG_2_MIN, TSEG_2_MAX);
117123
THEN("")
118124
{
119125
REQUIRE(is_valid_baudrate == true);
@@ -125,7 +131,7 @@ SCENARIO("calc_can_bit_timing", "[calc_can_bit_timing]")
125131
WHEN("CanBitRate::BR_1000k")
126132
{
127133
auto [is_valid_baudrate, baud_rate_prescaler, time_segment_1, time_segment_2] =
128-
util::calc_can_bit_timing(CanBitRate::BR_1000k, F_CAN_CLK_Hz, TQ_MIN, TQ_MAX, SYNC_JUMP_WIDTH);
134+
util::calc_can_bit_timing(CanBitRate::BR_1000k, F_CAN_CLK_Hz, TQ_MIN, TQ_MAX, TSEG_1_MIN, TSEG_1_MAX, TSEG_2_MIN, TSEG_2_MAX);
129135
THEN("")
130136
{
131137
REQUIRE(is_valid_baudrate == true);

libraries/CAN/src/CanUtil.cpp

Lines changed: 19 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
#include "CanUtil.h"
1616

1717
#include <math.h> /* modf */
18-
#include <iostream>
18+
1919
/**************************************************************************************
2020
* NAMESPACE
2121
**************************************************************************************/
@@ -27,15 +27,21 @@ namespace util
2727
* FUNCTION DEFINITION
2828
**************************************************************************************/
2929

30-
std::tuple<bool, uint32_t, uint32_t, uint32_t> calc_can_bit_timing(CanBitRate const can_bitrate, uint32_t const can_clock_Hz, uint32_t const tq_min, uint32_t const tq_max, uint32_t const sync_jump_width)
30+
std::tuple<bool, uint32_t, uint32_t, uint32_t>
31+
calc_can_bit_timing(CanBitRate const can_bitrate,
32+
uint32_t const can_clock_Hz,
33+
uint32_t const tq_min,
34+
uint32_t const tq_max,
35+
uint32_t const tseg1_min,
36+
uint32_t const tseg1_max,
37+
uint32_t const tseg2_min,
38+
uint32_t const tseg2_max)
3139
{
32-
/* Calculate the CAN bitrate based on the value of this functions parameter.
33-
*
34-
* Note: Concerning the calculation of
35-
* - _canfd_bit_timing_cfg.baud_rate_prescaler
40+
/* Note: Concerning the calculation of
41+
* - baud_rate_prescaler
3642
* - time_segment_1 (TSEG1)
3743
* - time_segment_2 (TSEG2)
38-
* also compare with Table 32.14, RA6M5 Group User Manual, Rev. 1.10.
44+
* also compare with section 30.4.3, RA4M1 Group User Manual, Rev. 1.00, October 2019.
3945
*/
4046
for (uint32_t tq = tq_max; tq >= tq_min; tq--)
4147
{
@@ -47,24 +53,15 @@ std::tuple<bool, uint32_t, uint32_t, uint32_t> calc_can_bit_timing(CanBitRate co
4753
/* If the fractional part is sufficiently close to zero, we have
4854
* found a valid prescaler configuration.
4955
*/
50-
std::cout << "can_bitrate = " << (int)can_bitrate << std::endl;
51-
std::cout << "tq = " << tq << std::endl;
52-
std::cout << "brp_fract = " << brp_fract << std::endl;
53-
if (brp_fract < 0.1)
56+
if (brp_fract < 0.01)
5457
{
55-
std::cout << "HELL YEAH" << std::endl;
5658
uint32_t const baud_rate_prescaler = static_cast<uint32_t>(brp_ipart);
5759
/* Assign TSEG1 and TSEG2 to set the sample point at 75%. */
58-
uint32_t const time_segment_1 = static_cast<int>(static_cast<float>(tq) * 0.75f) - sync_jump_width;
59-
/*
60-
if (time_segment_1 < 4 || time_segment_1 > 16)
61-
continue;
62-
*/
63-
uint32_t const time_segment_2 = tq - time_segment_1 - sync_jump_width - 1;
64-
//uint32_t const time_segment_2 = static_cast<int>(round(static_cast<float>(tq) * 0.25f)) - 1;
65-
std::cout << "time_segment_1 = " << time_segment_1 << std::endl;
66-
std::cout << "time_segment_2 = " << time_segment_2 << std::endl;
67-
60+
uint32_t const time_segment_1 = static_cast<int>(static_cast<float>(tq) * 0.75f) - 1;
61+
uint32_t const time_segment_2 = tq - time_segment_1 - 1;
62+
/* Check if the found values are within the allowed boundary. */
63+
if (time_segment_1 < tseg1_min || time_segment_1 > tseg1_max) continue;
64+
if (time_segment_2 < tseg2_min || time_segment_2 > tseg2_max) continue;
6865
/* We've found a valid configuration, exit here. */
6966
return std::make_tuple(true, baud_rate_prescaler, time_segment_1, time_segment_2);
7067
}

libraries/CAN/src/CanUtil.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@ std::tuple<bool, /* valid result found */
3636
uint32_t, /* baud_rate_prescaler */
3737
uint32_t, /* time_segment_1 */
3838
uint32_t> /* time_segment_2 */
39-
calc_can_bit_timing(CanBitRate const can_bitrate, uint32_t const can_clock_Hz, uint32_t const tq_min, uint32_t const tq_max, uint32_t const sync_jump_width);
39+
calc_can_bit_timing(CanBitRate const can_bitrate, uint32_t const can_clock_Hz, uint32_t const tq_min, uint32_t const tq_max,
40+
uint32_t const tseg1_min, uint32_t const tseg1_max, uint32_t const tseg2_min, uint32_t const tseg2_max);
4041

4142
/**************************************************************************************
4243
* NAMESPACE

libraries/CAN/src/R7FA4M1_CAN.cpp

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -49,14 +49,7 @@ R7FA4M1_CAN::R7FA4M1_CAN(int const can_tx_pin, int const can_rx_pin)
4949
, _is_error{false}
5050
, _err_code{0}
5151
, _can_rx_buf{}
52-
, _can_bit_timing_cfg
53-
{
54-
/* Actual bitrate: 250000 Hz. Actual Bit Time Ratio: 75 %. */
55-
.baud_rate_prescaler = 1 + 3 /* Division value of baud rate prescaler */,
56-
.time_segment_1 = 11,
57-
.time_segment_2 = 4,
58-
.synchronization_jump_width = 4
59-
}
52+
, _can_bit_timing_cfg{}
6053
, _can_mailbox_mask
6154
{
6255
CAN_DEFAULT_MASK,
@@ -114,7 +107,7 @@ R7FA4M1_CAN::R7FA4M1_CAN(int const can_tx_pin, int const can_rx_pin)
114107
}
115108
, _can_extended_cfg
116109
{
117-
.clock_source = CAN_CLOCK_SOURCE_CANMCLK,
110+
.clock_source = CAN_CLOCK_SOURCE_PCLKB,
118111
.p_mailbox_mask = _can_mailbox_mask,
119112
.p_mailbox = _can_mailbox,
120113
.global_id_mode = CAN_GLOBAL_ID_MODE_EXTENDED,
@@ -163,20 +156,23 @@ bool R7FA4M1_CAN::begin(CanBitRate const can_bitrate)
163156

164157
/* Calculate the CAN bitrate based on the value of this functions parameter.
165158
*/
166-
static uint32_t const F_CAN_CLK_Hz = 20*1000*1000UL; /* CANMCLK */
167-
static uint32_t const TQ_MIN = 8;
168-
static uint32_t const TQ_MAX = 25;
169-
static uint32_t const SYNC_JUMP_WIDTH = 4;
159+
static uint32_t const F_CAN_CLK_Hz = 24*1000*1000UL;
160+
static uint32_t const TQ_MIN = 8;
161+
static uint32_t const TQ_MAX = 25;
162+
static uint32_t const TSEG_1_MIN = 4;
163+
static uint32_t const TSEG_1_MAX = 16;
164+
static uint32_t const TSEG_2_MIN = 2;
165+
static uint32_t const TSEG_2_MAX = 8;
170166

171167
auto [is_valid_baudrate, baud_rate_prescaler, time_segment_1, time_segment_2] =
172-
util::calc_can_bit_timing(can_bitrate, F_CAN_CLK_Hz, TQ_MIN, TQ_MAX, SYNC_JUMP_WIDTH);
168+
util::calc_can_bit_timing(can_bitrate, F_CAN_CLK_Hz, TQ_MIN, TQ_MAX, TSEG_1_MIN, TSEG_1_MAX, TSEG_2_MIN, TSEG_2_MAX);
173169
init_ok &= is_valid_baudrate;
174170

175171
if (is_valid_baudrate) {
176172
_can_bit_timing_cfg.baud_rate_prescaler = baud_rate_prescaler;
177173
_can_bit_timing_cfg.time_segment_1 = time_segment_1;
178174
_can_bit_timing_cfg.time_segment_2 = time_segment_2;
179-
_can_bit_timing_cfg.synchronization_jump_width = SYNC_JUMP_WIDTH;
175+
_can_bit_timing_cfg.synchronization_jump_width = 1;
180176
}
181177

182178
/* Initialize the peripheral's FSP driver. */

libraries/CAN/src/R7FA6M5_CAN.cpp

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -45,14 +45,7 @@ R7FA6M5_CAN::R7FA6M5_CAN(int const can_tx_pin, int const can_rx_pin)
4545
, _is_error{false}
4646
, _err_code{0}
4747
, _can_rx_buf{}
48-
, _canfd_bit_timing_cfg
49-
{
50-
/* Actual bitrate: 250000 Hz. Actual sample point: 75 %. */
51-
.baud_rate_prescaler = 3,
52-
.time_segment_1 = 23,
53-
.time_segment_2 = 8,
54-
.synchronization_jump_width = 1
55-
}
48+
, _canfd_bit_timing_cfg{}
5649
, _canfd_afl{}
5750
, _canfd_global_cfg
5851
{
@@ -140,17 +133,22 @@ bool R7FA6M5_CAN::begin(CanBitRate const can_bitrate)
140133
/* Calculate the CAN bitrate based on the value of this functions parameter.
141134
*/
142135
static uint32_t const F_CAN_CLK_Hz = 24*1000*1000UL;
143-
static uint32_t const CAN_TIME_QUANTA_per_Bit = 32; /* TQ */
144-
145-
auto [is_valid_baudrate, baud_rate_prescaler, time_segment_1, time_segment_2, synchronization_jump_width] =
146-
util::calc_can_bit_timing(can_bitrate, F_CAN_CLK_Hz, CAN_TIME_QUANTA_per_Bit);
136+
static uint32_t const TQ_MIN = 5;
137+
static uint32_t const TQ_MAX = 49;
138+
static uint32_t const TSEG_1_MIN = 2;
139+
static uint32_t const TSEG_1_MAX = 39;
140+
static uint32_t const TSEG_2_MIN = 2;
141+
static uint32_t const TSEG_2_MAX = 10;
142+
143+
auto [is_valid_baudrate, baud_rate_prescaler, time_segment_1, time_segment_2] =
144+
util::calc_can_bit_timing(can_bitrate, F_CAN_CLK_Hz, TQ_MIN, TQ_MAX, TSEG_1_MIN, TSEG_1_MAX, TSEG_2_MIN, TSEG_2_MAX);
147145
init_ok &= is_valid_baudrate;
148146

149147
if (is_valid_baudrate) {
150148
_canfd_bit_timing_cfg.baud_rate_prescaler = baud_rate_prescaler;
151149
_canfd_bit_timing_cfg.time_segment_1 = time_segment_1;
152150
_canfd_bit_timing_cfg.time_segment_2 = time_segment_2;
153-
_canfd_bit_timing_cfg.synchronization_jump_width = synchronization_jump_width;
151+
_canfd_bit_timing_cfg.synchronization_jump_width = 1;
154152
}
155153

156154
/* Initialize the peripheral's FSP driver. */

0 commit comments

Comments
 (0)