diff --git a/cpu/samd5x/include/candev_samd5x.h b/cpu/samd5x/include/candev_samd5x.h index 5c846a867b..4353497720 100644 --- a/cpu/samd5x/include/candev_samd5x.h +++ b/cpu/samd5x/include/candev_samd5x.h @@ -109,7 +109,15 @@ typedef struct { * @ref can_conf_t::enable_pin will be set HIGH when active and LOW when * inactive. */ - bool enable_pin_active_low; + bool enable_pin_active_low : 1; + /** + * @brief Whether to disable automatic retransmission + * + * When set to `true`, a CAN frame will not be retransmitted on transmission + * failure (e.g. on missing ACK). Otherwise the frame will be transmitted + * again until it succeeds or the CAN controller goes into an error state. + */ + bool disable_automatic_retransmission : 1; } can_conf_t; #define HAVE_CAN_CONF_T diff --git a/cpu/samd5x/periph/can.c b/cpu/samd5x/periph/can.c index a4666c1ef2..0ebd9f7488 100644 --- a/cpu/samd5x/periph/can.c +++ b/cpu/samd5x/periph/can.c @@ -452,9 +452,15 @@ static int _init(candev_t *candev) if (IS_ACTIVE(ENABLE_DEBUG)) { _dump_msg_ram_section(dev); } - /* Disable automatic retransmission by default */ - /* This can be added as a configuration parameter for the CAN controller */ - dev->conf->can->CCCR.reg = CAN_CCCR_DAR; + + uint32_t cccr = dev->conf->can->CCCR.reg; + cccr &= ~(CAN_CCCR_DAR); + + if (dev->conf->disable_automatic_retransmission) { + cccr |= CAN_CCCR_DAR; + } + + dev->conf->can->CCCR.reg = cccr; /* Reject all remote frames */ dev->conf->can->GFC.reg = CAN_GFC_RRFE | CAN_GFC_RRFS;