From 9bd97eb0b81e8ee3183084b2f10e21a4c2f6c09d Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Thu, 5 May 2022 13:46:43 +0200 Subject: [PATCH] drivers: can: add CAN_MODE_FD Add support for enabling/disabling CAN-FD frame transmission/reception at run-time. Fixes: #45303 Signed-off-by: Henrik Brix Andersen --- drivers/can/can_mcan.c | 24 +++++++++++++++++------- include/zephyr/drivers/can.h | 3 +++ tests/drivers/can/canfd/src/main.c | 2 +- 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/drivers/can/can_mcan.c b/drivers/can/can_mcan.c index a80a96e7347..4afae019f9f 100644 --- a/drivers/can/can_mcan.c +++ b/drivers/can/can_mcan.c @@ -246,10 +246,17 @@ int can_mcan_set_mode(const struct device *dev, can_mode_t mode) struct can_mcan_reg *can = cfg->can; int ret; +#ifdef CONFIG_CAN_FD_MODE + if ((mode & ~(CAN_MODE_LOOPBACK | CAN_MODE_LISTENONLY | CAN_MODE_FD)) != 0) { + LOG_ERR("unsupported mode: 0x%08x", mode); + return -ENOTSUP; + } +#else if ((mode & ~(CAN_MODE_LOOPBACK | CAN_MODE_LISTENONLY)) != 0) { LOG_ERR("unsupported mode: 0x%08x", mode); return -ENOTSUP; } +#endif /* CONFIG_CAN_FD_MODE */ if (cfg->phy != NULL) { ret = can_transceiver_enable(cfg->phy); @@ -289,6 +296,14 @@ int can_mcan_set_mode(const struct device *dev, can_mode_t mode) can->cccr &= ~CAN_MCAN_CCCR_MON; } +#ifdef CONFIG_CAN_FD_MODE + if ((mode & CAN_MODE_FD) != 0) { + can->cccr |= CAN_MCAN_CCCR_FDOE | CAN_MCAN_CCCR_BRSE; + } else { + can->cccr &= ~(CAN_MCAN_CCCR_FDOE | CAN_MCAN_CCCR_BRSE); + } +#endif /* CONFIG_CAN_FD_MODE */ + ret = can_leave_init_mode(can, K_MSEC(CAN_INIT_TIMEOUT)); if (ret) { LOG_ERR("Failed to leave init mode"); @@ -407,13 +422,8 @@ int can_mcan_init(const struct device *dev) / 16 + 5) << CAN_MCAN_RXESC_RBDS_POS); } #endif - -#ifdef CONFIG_CAN_FD_MODE - can->cccr |= CAN_MCAN_CCCR_FDOE | CAN_MCAN_CCCR_BRSE; -#else - can->cccr &= ~(CAN_MCAN_CCCR_FDOE | CAN_MCAN_CCCR_BRSE); -#endif - can->cccr &= ~(CAN_MCAN_CCCR_TEST | CAN_MCAN_CCCR_MON | + can->cccr &= ~(CAN_MCAN_CCCR_FDOE | CAN_MCAN_CCCR_BRSE | + CAN_MCAN_CCCR_TEST | CAN_MCAN_CCCR_MON | CAN_MCAN_CCCR_ASM); can->test &= ~(CAN_MCAN_TEST_LBCK); diff --git a/include/zephyr/drivers/can.h b/include/zephyr/drivers/can.h index 35756b57d14..2a55986932b 100644 --- a/include/zephyr/drivers/can.h +++ b/include/zephyr/drivers/can.h @@ -94,6 +94,9 @@ extern "C" { /** Controller is not allowed to send dominant bits. */ #define CAN_MODE_LISTENONLY BIT(1) +/** Controller allows transmitting/receiving CAN-FD frames. */ +#define CAN_MODE_FD BIT(2) + /** @} */ /** diff --git a/tests/drivers/can/canfd/src/main.c b/tests/drivers/can/canfd/src/main.c index 2e0848b7af2..91da287eaea 100644 --- a/tests/drivers/can/canfd/src/main.c +++ b/tests/drivers/can/canfd/src/main.c @@ -349,7 +349,7 @@ static void test_set_loopback(void) { int err; - err = can_set_mode(can_dev, CAN_MODE_LOOPBACK); + err = can_set_mode(can_dev, CAN_MODE_LOOPBACK | CAN_MODE_FD); zassert_equal(err, 0, "failed to set loopback-mode (err %d)", err); }