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 <hebad@vestas.com>
This commit is contained in:
Henrik Brix Andersen 2022-01-14 15:17:32 +01:00 committed by Anas Nashif
commit b6f6069b99
3 changed files with 15 additions and 0 deletions

View file

@ -489,6 +489,10 @@ static int can_stm32_init(const struct device *dev)
#ifdef CONFIG_CAN_AUTO_BUS_OFF_RECOVERY #ifdef CONFIG_CAN_AUTO_BUS_OFF_RECOVERY
can->MCR |= CAN_MCR_ABOM; can->MCR |= CAN_MCR_ABOM;
#endif #endif
if (cfg->one_shot) {
can->MCR |= CAN_MCR_NART;
}
timing.sjw = cfg->sjw; timing.sjw = cfg->sjw;
if (cfg->sample_point && USE_SP_ALGO) { if (cfg->sample_point && USE_SP_ALGO) {
ret = can_calc_timing(dev, &timing, cfg->bus_speed, 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) + .prop_ts1 = DT_PROP_OR(DT_NODELABEL(can1), prop_seg, 0) +
DT_PROP_OR(DT_NODELABEL(can1), phase_seg1, 0), DT_PROP_OR(DT_NODELABEL(can1), phase_seg1, 0),
.ts2 = DT_PROP_OR(DT_NODELABEL(can1), phase_seg2, 0), .ts2 = DT_PROP_OR(DT_NODELABEL(can1), phase_seg2, 0),
.one_shot = DT_PROP(DT_NODELABEL(can1), one_shot),
.pclken = { .pclken = {
.enr = DT_CLOCKS_CELL(DT_NODELABEL(can1), bits), .enr = DT_CLOCKS_CELL(DT_NODELABEL(can1), bits),
.bus = DT_CLOCKS_CELL(DT_NODELABEL(can1), bus), .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) + .prop_ts1 = DT_PROP_OR(DT_NODELABEL(can2), prop_seg, 0) +
DT_PROP_OR(DT_NODELABEL(can2), phase_seg1, 0), DT_PROP_OR(DT_NODELABEL(can2), phase_seg1, 0),
.ts2 = DT_PROP_OR(DT_NODELABEL(can2), phase_seg2, 0), .ts2 = DT_PROP_OR(DT_NODELABEL(can2), phase_seg2, 0),
.one_shot = DT_PROP(DT_NODELABEL(can2), one_shot),
.pclken = { .pclken = {
.enr = DT_CLOCKS_CELL(DT_NODELABEL(can2), bits), .enr = DT_CLOCKS_CELL(DT_NODELABEL(can2), bits),
.bus = DT_CLOCKS_CELL(DT_NODELABEL(can2), bus), .bus = DT_CLOCKS_CELL(DT_NODELABEL(can2), bus),

View file

@ -76,6 +76,7 @@ struct can_stm32_config {
uint8_t sjw; uint8_t sjw;
uint8_t prop_ts1; uint8_t prop_ts1;
uint8_t ts2; uint8_t ts2;
bool one_shot;
struct stm32_pclken pclken; struct stm32_pclken pclken;
void (*config_irq)(CAN_TypeDef *can); void (*config_irq)(CAN_TypeDef *can);
const struct pinctrl_dev_config *pcfg; const struct pinctrl_dev_config *pcfg;

View file

@ -20,6 +20,14 @@ properties:
pinctrl-names: pinctrl-names:
required: true 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: master-can-reg:
type: int type: int
required: false required: false