Skip to content

Commit 5e0ca9b

Browse files
alexanderwachtergalak
authored andcommitted
drivers: can: sjw == 0 in can_set_timing should not change sjw
If the supplied sjw in the timing parameters is zero, the sjw parameter should not be changed. This fixes the uninitialized swj in can_set_bitrate. Signed-off-by: Alexander Wachter <[email protected]>
1 parent 6910d4d commit 5e0ca9b

File tree

6 files changed

+44
-14
lines changed

6 files changed

+44
-14
lines changed

drivers/can/can_mcan.c

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@ void can_mcan_configure_timing(struct can_mcan_reg *can,
7979
const struct can_timing *timing_data)
8080
{
8181
if (timing) {
82+
uint32_t nbtp_sjw = can->nbtp & CAN_MCAN_NBTP_NSJW_MSK;
83+
8284
__ASSERT_NO_MSG(timing->prop_seg == 0);
8385
__ASSERT_NO_MSG(timing->phase_seg1 <= 0x100 &&
8486
timing->phase_seg1 > 0);
@@ -92,14 +94,21 @@ void can_mcan_configure_timing(struct can_mcan_reg *can,
9294
CAN_MCAN_NBTP_NTSEG1_POS |
9395
(((uint32_t)timing->phase_seg2 - 1UL) & 0x7F) <<
9496
CAN_MCAN_NBTP_NTSEG2_POS |
95-
(((uint32_t)timing->sjw - 1UL) & 0x7F) <<
96-
CAN_MCAN_NBTP_NSJW_POS |
9797
(((uint32_t)timing->prescaler - 1UL) & 0x1FF) <<
9898
CAN_MCAN_NBTP_NBRP_POS;
99+
100+
if (timing->sjw == CAN_SJW_NO_CHANGE) {
101+
can->nbtp |= nbtp_sjw;
102+
} else {
103+
can->nbtp |= (((uint32_t)timing->sjw - 1UL) & 0x7F) <<
104+
CAN_MCAN_NBTP_NSJW_POS;
105+
}
99106
}
100107

101108
#ifdef CONFIG_CAN_FD_MODE
102109
if (timing_data) {
110+
uint32_t dbtp_sjw = can->dbtp & CAN_MCAN_DBTP_DSJW_MSK;
111+
103112
__ASSERT_NO_MSG(timing_data->prop_seg == 0);
104113
__ASSERT_NO_MSG(timing_data->phase_seg1 <= 0x20 &&
105114
timing_data->phase_seg1 > 0);
@@ -112,12 +121,17 @@ void can_mcan_configure_timing(struct can_mcan_reg *can,
112121

113122
can->dbtp = (((uint32_t)timing_data->phase_seg1 - 1UL) & 0x1F) <<
114123
CAN_MCAN_DBTP_DTSEG1_POS |
115-
(((uint32_t)timing_data->phase_seg2 - 1UL) & 0x0F) <<
124+
(((uint32_t)timing_data->phase_seg2 - 1UL) & 0x0F) <<
116125
CAN_MCAN_DBTP_DTSEG2_POS |
117-
(((uint32_t)timing_data->sjw - 1UL) & 0x0F) <<
118-
CAN_MCAN_DBTP_DSJW_POS |
119126
(((uint32_t)timing_data->prescaler - 1UL) & 0x1F) <<
120127
CAN_MCAN_DBTP_DBRP_POS;
128+
129+
if (timing_data->sjw == CAN_SJW_NO_CHANGE) {
130+
can->nbtp |= dbtp_sjw;
131+
} else {
132+
can->nbtp |= (((uint32_t)timing_data->sjw - 1UL) & 0x0F) <<
133+
CAN_MCAN_DBTP_DSJW_POS;
134+
}
121135
}
122136
#endif
123137
}

drivers/can/can_mcp2515.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -335,8 +335,11 @@ static int mcp2515_set_timing(const struct device *dev,
335335
/* CNF1; SJW<7:6> | BRP<5:0> */
336336
__ASSERT(timing->prescaler > 0, "Prescaler should be bigger than zero");
337337
uint8_t brp = timing->prescaler - 1;
338-
const uint8_t sjw = (timing->sjw - 1) << 6;
339-
uint8_t cnf1 = sjw | brp;
338+
if (timing->sjw != CAN_SJW_NO_CHANGE) {
339+
dev_data->sjw = (timing->sjw - 1) << 6;
340+
}
341+
342+
uint8_t cnf1 = dev_data->sjw | brp;
340343

341344
/* CNF2; BTLMODE<7>|SAM<6>|PHSEG1<5:3>|PRSEG<2:0> */
342345
const uint8_t btlmode = 1 << 7;
@@ -363,8 +366,7 @@ static int mcp2515_set_timing(const struct device *dev,
363366
const uint8_t rx0_ctrl = BIT(6) | BIT(5) | BIT(2);
364367
const uint8_t rx1_ctrl = BIT(6) | BIT(5);
365368

366-
__ASSERT((timing->sjw >= 1) && (timing->sjw <= 4),
367-
"1 <= SJW <= 4");
369+
__ASSERT(timing->sjw <= 4, "1 <= SJW <= 4");
368370
__ASSERT((timing->prop_seg >= 1) && (timing->prop_seg <= 8),
369371
"1 <= PROP <= 8");
370372
__ASSERT((timing->phase_seg1 >= 1) && (timing->phase_seg1 <= 8),

drivers/can/can_mcp2515.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ struct mcp2515_data {
5454
/* general data */
5555
struct k_mutex mutex;
5656
enum can_state old_state;
57+
uint8_t sjw;
5758
};
5859

5960
struct mcp2515_config {

drivers/can/can_mcux_flexcan.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,13 +134,17 @@ static int mcux_flexcan_set_timing(const struct device *dev,
134134
ARG_UNUSED(timing_data);
135135
struct mcux_flexcan_data *data = dev->data;
136136
const struct mcux_flexcan_config *config = dev->config;
137+
uint8_t sjw_backup = data->timing.sjw;
137138
flexcan_timing_config_t timing_tmp;
138139

139140
if (!timing) {
140141
return -EINVAL;
141142
}
142143

143144
data->timing = *timing;
145+
if (timing->sjw == CAN_SJW_NO_CHANGE) {
146+
data->timing.sjw = sjw_backup;
147+
}
144148

145149
timing_tmp.preDivider = data->timing.prescaler - 1U;
146150
timing_tmp.rJumpwidth = data->timing.sjw - 1U;

drivers/can/can_stm32.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -371,15 +371,16 @@ int can_stm32_set_timing(const struct device *dev,
371371
goto done;
372372
}
373373

374-
can->BTR &= ~(CAN_BTR_BRP_Msk | CAN_BTR_TS1_Msk |
375-
CAN_BTR_TS2_Msk | CAN_BTR_SJW_Msk);
376-
377-
can->BTR |=
374+
can->BTR = (can->BTR & ~(CAN_BTR_BRP_Msk | CAN_BTR_TS1_Msk | CAN_BTR_TS2_Msk)) |
378375
(((timing->phase_seg1 - 1) << CAN_BTR_TS1_Pos) & CAN_BTR_TS1_Msk) |
379376
(((timing->phase_seg2 - 1) << CAN_BTR_TS2_Pos) & CAN_BTR_TS2_Msk) |
380-
(((timing->sjw - 1) << CAN_BTR_SJW_Pos) & CAN_BTR_SJW_Msk) |
381377
(((timing->prescaler - 1) << CAN_BTR_BRP_Pos) & CAN_BTR_BRP_Msk);
382378

379+
if (timing->sjw != CAN_SJW_NO_CHANGE) {
380+
can->BTR = (can->BTR & ~CAN_BTR_SJW_Msk) |
381+
(((timing->sjw - 1) << CAN_BTR_SJW_Pos) & CAN_BTR_SJW_Msk);
382+
}
383+
383384
ret = can_leave_init_mode(can);
384385
if (ret) {
385386
LOG_ERR("Failed to leave init mode");

include/drivers/can.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,8 @@ struct can_bus_err_cnt {
259259
uint8_t rx_err_cnt;
260260
};
261261

262+
/** SWJ value to indicate that the SJW should not be changed */
263+
#define CAN_SJW_NO_CHANGE 0
262264

263265
/**
264266
* @brief canbus timings
@@ -727,6 +729,8 @@ static inline int z_impl_can_set_mode(const struct device *dev,
727729
/**
728730
* @brief Configure timing of a host controller.
729731
*
732+
* If the sjw equals CAN_SJW_NO_CHANGE, the sjw parameter is not changed.
733+
*
730734
* The second parameter timing_data is only relevant for CAN-FD.
731735
* If the controller does not support CAN-FD or the FD mode is not enabled,
732736
* this parameter is ignored.
@@ -783,12 +787,16 @@ static inline int can_set_bitrate(const struct device *dev,
783787
return -EINVAL;
784788
}
785789

790+
timing.sjw = CAN_SJW_NO_CHANGE;
791+
786792
#ifdef CONFIG_CAN_FD_MODE
787793
ret = can_calc_timing_data(dev, &timing_data, bitrate_data, 875);
788794
if (ret < 0) {
789795
return -EINVAL;
790796
}
791797

798+
timing_data.sjw = CAN_SJW_NO_CHANGE;
799+
792800
return can_set_timing(dev, &timing, &timing_data);
793801
#else
794802
return can_set_timing(dev, &timing, NULL);

0 commit comments

Comments
 (0)