From b6f6069b99871381ab7a503302f7e1c81ad1c874 Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Fri, 14 Jan 2022 15:17:32 +0100 Subject: [PATCH] drivers: can: stm32: add support for disabling automatic retransmissions Add support for disabling automatic retransmission of CAN frames (similar to CAN "one-shot" mode in the Linux kernel). Signed-off-by: Henrik Brix Andersen --- drivers/can/can_stm32.c | 6 ++++++ drivers/can/can_stm32.h | 1 + dts/bindings/can/st,stm32-can.yaml | 8 ++++++++ 3 files changed, 15 insertions(+) diff --git a/drivers/can/can_stm32.c b/drivers/can/can_stm32.c index 6a19b78c8c1..7f71eaa992c 100644 --- a/drivers/can/can_stm32.c +++ b/drivers/can/can_stm32.c @@ -489,6 +489,10 @@ static int can_stm32_init(const struct device *dev) #ifdef CONFIG_CAN_AUTO_BUS_OFF_RECOVERY can->MCR |= CAN_MCR_ABOM; #endif + if (cfg->one_shot) { + can->MCR |= CAN_MCR_NART; + } + timing.sjw = cfg->sjw; if (cfg->sample_point && USE_SP_ALGO) { ret = can_calc_timing(dev, &timing, cfg->bus_speed, @@ -1148,6 +1152,7 @@ static const struct can_stm32_config can_stm32_cfg_1 = { .prop_ts1 = DT_PROP_OR(DT_NODELABEL(can1), prop_seg, 0) + DT_PROP_OR(DT_NODELABEL(can1), phase_seg1, 0), .ts2 = DT_PROP_OR(DT_NODELABEL(can1), phase_seg2, 0), + .one_shot = DT_PROP(DT_NODELABEL(can1), one_shot), .pclken = { .enr = DT_CLOCKS_CELL(DT_NODELABEL(can1), bits), .bus = DT_CLOCKS_CELL(DT_NODELABEL(can1), bus), @@ -1245,6 +1250,7 @@ static const struct can_stm32_config can_stm32_cfg_2 = { .prop_ts1 = DT_PROP_OR(DT_NODELABEL(can2), prop_seg, 0) + DT_PROP_OR(DT_NODELABEL(can2), phase_seg1, 0), .ts2 = DT_PROP_OR(DT_NODELABEL(can2), phase_seg2, 0), + .one_shot = DT_PROP(DT_NODELABEL(can2), one_shot), .pclken = { .enr = DT_CLOCKS_CELL(DT_NODELABEL(can2), bits), .bus = DT_CLOCKS_CELL(DT_NODELABEL(can2), bus), diff --git a/drivers/can/can_stm32.h b/drivers/can/can_stm32.h index 5e83dedab87..a90b9d5c68c 100644 --- a/drivers/can/can_stm32.h +++ b/drivers/can/can_stm32.h @@ -76,6 +76,7 @@ struct can_stm32_config { uint8_t sjw; uint8_t prop_ts1; uint8_t ts2; + bool one_shot; struct stm32_pclken pclken; void (*config_irq)(CAN_TypeDef *can); const struct pinctrl_dev_config *pcfg; diff --git a/dts/bindings/can/st,stm32-can.yaml b/dts/bindings/can/st,stm32-can.yaml index 623733dcd0b..7462ec3a510 100644 --- a/dts/bindings/can/st,stm32-can.yaml +++ b/dts/bindings/can/st,stm32-can.yaml @@ -20,6 +20,14 @@ properties: pinctrl-names: required: true + one-shot: + type: boolean + required: false + description: | + Disable automatic retransmissions. A CAN frame will only be transmitted + once, independently of the transmission result (successful, error, or + arbitration lost). + master-can-reg: type: int required: false