drivers: can: convert enum can_mode to a bit field
Convert the can_mode enum to a bit field to prepare for future extensions (CAN-FD mode, transmitter delay compensation, one-shot mode, 3-samples mode, ...). Rename the existing modes: - CAN_NORMAL_MODE -> CAN_MODE_NORMAL - CAN_SILENT_MODE -> CAN_MODE_LISTENONLY - CAN_LOOPBACK_MODE -> CAN_MODE_LOOPBACK These mode names align with the Linux naming for CAN control modes. The old CAN_SILENT_LOOPBACK_MODE can be set with the bitmask (CAN_MODE_LISTENONLY | CAN_MODE_LOOPBACK). Signed-off-by: Henrik Brix Andersen <hebad@vestas.com>
This commit is contained in:
parent
85c2c9147b
commit
3f97d11afd
25 changed files with 155 additions and 110 deletions
|
@ -138,7 +138,7 @@ static inline int z_vrfy_can_get_max_filters(const struct device *dev, enum can_
|
|||
}
|
||||
#include <syscalls/can_get_max_filters_mrsh.c>
|
||||
|
||||
static inline int z_vrfy_can_set_mode(const struct device *dev, enum can_mode mode)
|
||||
static inline int z_vrfy_can_set_mode(const struct device *dev, can_mode_t mode)
|
||||
{
|
||||
Z_OOPS(Z_SYSCALL_DRIVER_CAN(dev, set_mode));
|
||||
|
||||
|
|
|
@ -197,11 +197,11 @@ static void can_loopback_remove_rx_filter(const struct device *dev, int filter_i
|
|||
k_mutex_unlock(&data->mtx);
|
||||
}
|
||||
|
||||
static int can_loopback_set_mode(const struct device *dev, enum can_mode mode)
|
||||
static int can_loopback_set_mode(const struct device *dev, can_mode_t mode)
|
||||
{
|
||||
struct can_loopback_data *data = dev->data;
|
||||
|
||||
data->loopback = mode == CAN_LOOPBACK_MODE ? 1 : 0;
|
||||
data->loopback = (mode & CAN_MODE_LOOPBACK) != 0 ? 1 : 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -240,12 +240,17 @@ int can_mcan_set_timing_data(const struct device *dev,
|
|||
}
|
||||
#endif /* CONFIG_CAN_FD_MODE */
|
||||
|
||||
int can_mcan_set_mode(const struct device *dev, enum can_mode mode)
|
||||
int can_mcan_set_mode(const struct device *dev, can_mode_t mode)
|
||||
{
|
||||
const struct can_mcan_config *cfg = dev->config;
|
||||
struct can_mcan_reg *can = cfg->can;
|
||||
int ret;
|
||||
|
||||
if ((mode & ~(CAN_MODE_LOOPBACK | CAN_MODE_LISTENONLY)) != 0) {
|
||||
LOG_ERR("unsupported mode: 0x%08x", mode);
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
if (cfg->phy != NULL) {
|
||||
ret = can_transceiver_enable(cfg->phy);
|
||||
if (ret != 0) {
|
||||
|
@ -269,32 +274,19 @@ int can_mcan_set_mode(const struct device *dev, enum can_mode mode)
|
|||
/* Configuration Change Enable */
|
||||
can->cccr |= CAN_MCAN_CCCR_CCE;
|
||||
|
||||
switch (mode) {
|
||||
case CAN_NORMAL_MODE:
|
||||
LOG_DBG("Config normal mode");
|
||||
can->cccr &= ~(CAN_MCAN_CCCR_TEST | CAN_MCAN_CCCR_MON);
|
||||
break;
|
||||
|
||||
case CAN_SILENT_MODE:
|
||||
LOG_DBG("Config silent mode");
|
||||
can->cccr &= ~CAN_MCAN_CCCR_TEST;
|
||||
can->cccr |= CAN_MCAN_CCCR_MON;
|
||||
break;
|
||||
|
||||
case CAN_LOOPBACK_MODE:
|
||||
LOG_DBG("Config loopback mode");
|
||||
can->cccr &= ~CAN_MCAN_CCCR_MON;
|
||||
if ((mode & CAN_MODE_LOOPBACK) != 0) {
|
||||
/* Loopback mode */
|
||||
can->cccr |= CAN_MCAN_CCCR_TEST;
|
||||
can->test |= CAN_MCAN_TEST_LBCK;
|
||||
break;
|
||||
} else {
|
||||
can->cccr &= ~CAN_MCAN_CCCR_TEST;
|
||||
}
|
||||
|
||||
case CAN_SILENT_LOOPBACK_MODE:
|
||||
LOG_DBG("Config silent loopback mode");
|
||||
can->cccr |= (CAN_MCAN_CCCR_TEST | CAN_MCAN_CCCR_MON);
|
||||
can->test |= CAN_MCAN_TEST_LBCK;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
if ((mode & CAN_MODE_LISTENONLY) != 0) {
|
||||
/* Bus monitoring mode */
|
||||
can->cccr |= CAN_MCAN_CCCR_MON;
|
||||
} else {
|
||||
can->cccr &= ~CAN_MCAN_CCCR_MON;
|
||||
}
|
||||
|
||||
ret = can_leave_init_mode(can, K_MSEC(CAN_INIT_TIMEOUT));
|
||||
|
|
|
@ -257,7 +257,7 @@ struct can_mcan_reg;
|
|||
.custom = _custom_data, \
|
||||
}
|
||||
|
||||
int can_mcan_set_mode(const struct device *dev, enum can_mode mode);
|
||||
int can_mcan_set_mode(const struct device *dev, can_mode_t mode);
|
||||
|
||||
int can_mcan_set_timing(const struct device *dev,
|
||||
const struct can_timing *timing);
|
||||
|
|
|
@ -440,7 +440,7 @@ done:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int mcp2515_set_mode(const struct device *dev, enum can_mode mode)
|
||||
static int mcp2515_set_mode(const struct device *dev, can_mode_t mode)
|
||||
{
|
||||
const struct mcp2515_config *dev_cfg = dev->config;
|
||||
struct mcp2515_data *dev_data = dev->data;
|
||||
|
@ -448,13 +448,13 @@ static int mcp2515_set_mode(const struct device *dev, enum can_mode mode)
|
|||
int ret;
|
||||
|
||||
switch (mode) {
|
||||
case CAN_NORMAL_MODE:
|
||||
case CAN_MODE_NORMAL:
|
||||
mcp2515_mode = MCP2515_MODE_NORMAL;
|
||||
break;
|
||||
case CAN_SILENT_MODE:
|
||||
case CAN_MODE_LISTENONLY:
|
||||
mcp2515_mode = MCP2515_MODE_SILENT;
|
||||
break;
|
||||
case CAN_LOOPBACK_MODE:
|
||||
case CAN_MODE_LOOPBACK:
|
||||
mcp2515_mode = MCP2515_MODE_LOOPBACK;
|
||||
break;
|
||||
default:
|
||||
|
@ -952,7 +952,7 @@ static int mcp2515_init(const struct device *dev)
|
|||
return ret;
|
||||
}
|
||||
|
||||
ret = can_set_mode(dev, CAN_NORMAL_MODE);
|
||||
ret = can_set_mode(dev, CAN_MODE_NORMAL);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -179,13 +179,18 @@ static int mcux_flexcan_set_timing(const struct device *dev,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int mcux_flexcan_set_mode(const struct device *dev, enum can_mode mode)
|
||||
static int mcux_flexcan_set_mode(const struct device *dev, can_mode_t mode)
|
||||
{
|
||||
const struct mcux_flexcan_config *config = dev->config;
|
||||
uint32_t ctrl1;
|
||||
uint32_t mcr;
|
||||
int err;
|
||||
|
||||
if ((mode & ~(CAN_MODE_LOOPBACK | CAN_MODE_LISTENONLY)) != 0) {
|
||||
LOG_ERR("unsupported mode: 0x%08x", mode);
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
if (config->phy != NULL) {
|
||||
err = can_transceiver_enable(config->phy);
|
||||
if (err != 0) {
|
||||
|
@ -199,7 +204,7 @@ static int mcux_flexcan_set_mode(const struct device *dev, enum can_mode mode)
|
|||
ctrl1 = config->base->CTRL1;
|
||||
mcr = config->base->MCR;
|
||||
|
||||
if (mode == CAN_LOOPBACK_MODE || mode == CAN_SILENT_LOOPBACK_MODE) {
|
||||
if ((mode & CAN_MODE_LOOPBACK) != 0) {
|
||||
/* Enable loopback and self-reception */
|
||||
ctrl1 |= CAN_CTRL1_LPB_MASK;
|
||||
mcr &= ~(CAN_MCR_SRXDIS_MASK);
|
||||
|
@ -209,7 +214,7 @@ static int mcux_flexcan_set_mode(const struct device *dev, enum can_mode mode)
|
|||
mcr |= CAN_MCR_SRXDIS_MASK;
|
||||
}
|
||||
|
||||
if (mode == CAN_SILENT_MODE || mode == CAN_SILENT_LOOPBACK_MODE) {
|
||||
if ((mode & CAN_MODE_LISTENONLY) != 0) {
|
||||
/* Enable listen-only mode */
|
||||
ctrl1 |= CAN_CTRL1_LOM_MASK;
|
||||
} else {
|
||||
|
|
|
@ -566,30 +566,34 @@ static int can_rcar_enter_operation_mode(const struct can_rcar_cfg *config)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int can_rcar_set_mode(const struct device *dev, enum can_mode mode)
|
||||
static int can_rcar_set_mode(const struct device *dev, can_mode_t mode)
|
||||
{
|
||||
const struct can_rcar_cfg *config = dev->config;
|
||||
struct can_rcar_data *data = dev->data;
|
||||
uint8_t tcr = 0;
|
||||
int ret = 0;
|
||||
|
||||
if ((mode & ~(CAN_MODE_LOOPBACK | CAN_MODE_LISTENONLY)) != 0) {
|
||||
LOG_ERR("Unsupported mode: 0x%08x", mode);
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
k_mutex_lock(&data->inst_mutex, K_FOREVER);
|
||||
switch (mode) {
|
||||
case CAN_NORMAL_MODE:
|
||||
tcr = 0;
|
||||
break;
|
||||
/*Controller is not allowed to send dominant bits*/
|
||||
case CAN_SILENT_MODE:
|
||||
tcr = RCAR_CAN_TCR_LISTEN_ONLY | RCAR_CAN_TCR_TSTE;
|
||||
break;
|
||||
/*Controller is in loopback mode (receive own messages)*/
|
||||
case CAN_LOOPBACK_MODE:
|
||||
tcr = RCAR_CAN_TCR_INT_LOOP | RCAR_CAN_TCR_TSTE;
|
||||
break;
|
||||
/*Combination of loopback and silent*/
|
||||
case CAN_SILENT_LOOPBACK_MODE:
|
||||
|
||||
if ((mode & (CAN_MODE_LOOPBACK | CAN_MODE_LISTENONLY)) ==
|
||||
(CAN_MODE_LOOPBACK | CAN_MODE_LISTENONLY)) {
|
||||
LOG_ERR("Combination of loopback and listenonly modes not supported");
|
||||
ret = -ENOTSUP;
|
||||
goto unlock;
|
||||
} else if ((mode & CAN_MODE_LOOPBACK) != 0) {
|
||||
/* Loopback mode */
|
||||
tcr = RCAR_CAN_TCR_INT_LOOP | RCAR_CAN_TCR_TSTE;
|
||||
} else if ((mode & CAN_MODE_LISTENONLY) != 0) {
|
||||
/* Listen-only mode */
|
||||
tcr = RCAR_CAN_TCR_LISTEN_ONLY | RCAR_CAN_TCR_TSTE;
|
||||
} else {
|
||||
/* Normal mode */
|
||||
tcr = 0;
|
||||
}
|
||||
|
||||
/* Enable CAN transceiver */
|
||||
|
@ -957,7 +961,7 @@ static int can_rcar_init(const struct device *dev)
|
|||
return ret;
|
||||
}
|
||||
|
||||
ret = can_rcar_set_mode(dev, CAN_NORMAL_MODE);
|
||||
ret = can_rcar_set_mode(dev, CAN_MODE_NORMAL);
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ static struct k_poll_event msgq_events[1] = {
|
|||
};
|
||||
|
||||
static inline int read_config_options(const struct shell *sh, int pos,
|
||||
char **argv, bool *silent, bool *loopback)
|
||||
char **argv, bool *listenonly, bool *loopback)
|
||||
{
|
||||
char *arg = argv[pos];
|
||||
|
||||
|
@ -31,10 +31,10 @@ static inline int read_config_options(const struct shell *sh, int pos,
|
|||
for (arg = &arg[1]; *arg; arg++) {
|
||||
switch (*arg) {
|
||||
case 's':
|
||||
if (silent == NULL) {
|
||||
if (listenonly == NULL) {
|
||||
shell_error(sh, "Unknown option %c", *arg);
|
||||
} else {
|
||||
*silent = true;
|
||||
*listenonly = true;
|
||||
}
|
||||
break;
|
||||
case 'l':
|
||||
|
@ -231,8 +231,8 @@ static int cmd_config(const struct shell *sh, size_t argc, char **argv)
|
|||
{
|
||||
const struct device *can_dev;
|
||||
int pos = 1;
|
||||
bool silent = false, loopback = false;
|
||||
enum can_mode mode;
|
||||
bool listenonly = false, loopback = false;
|
||||
can_mode_t mode = CAN_MODE_NORMAL;
|
||||
uint32_t bitrate;
|
||||
int ret;
|
||||
|
||||
|
@ -245,19 +245,17 @@ static int cmd_config(const struct shell *sh, size_t argc, char **argv)
|
|||
|
||||
pos++;
|
||||
|
||||
pos = read_config_options(sh, pos, argv, &silent, &loopback);
|
||||
pos = read_config_options(sh, pos, argv, &listenonly, &loopback);
|
||||
if (pos < 0) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (silent && loopback) {
|
||||
mode = CAN_SILENT_LOOPBACK_MODE;
|
||||
} else if (silent) {
|
||||
mode = CAN_SILENT_MODE;
|
||||
} else if (loopback) {
|
||||
mode = CAN_LOOPBACK_MODE;
|
||||
} else {
|
||||
mode = CAN_NORMAL_MODE;
|
||||
if (listenonly) {
|
||||
mode |= CAN_MODE_LISTENONLY;
|
||||
}
|
||||
|
||||
if (loopback) {
|
||||
mode |= CAN_MODE_LOOPBACK;
|
||||
}
|
||||
|
||||
ret = can_set_mode(can_dev, mode);
|
||||
|
@ -447,8 +445,8 @@ SHELL_STATIC_SUBCMD_SET_CREATE(sub_can,
|
|||
SHELL_CMD_ARG(config, NULL,
|
||||
"Configure CAN controller.\n"
|
||||
" Usage: config device_name [-sl] bitrate\n"
|
||||
" -s Silent mode\n"
|
||||
" -l Listen-only mode",
|
||||
" -s Listen-only mode\n"
|
||||
" -l Loopback mode",
|
||||
cmd_config, 3, 1),
|
||||
SHELL_CMD_ARG(send, NULL,
|
||||
"Send a CAN frame.\n"
|
||||
|
|
|
@ -341,7 +341,7 @@ static int can_leave_sleep_mode(CAN_TypeDef *can)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int can_stm32_set_mode(const struct device *dev, enum can_mode mode)
|
||||
static int can_stm32_set_mode(const struct device *dev, can_mode_t mode)
|
||||
{
|
||||
const struct can_stm32_config *cfg = dev->config;
|
||||
CAN_TypeDef *can = cfg->can;
|
||||
|
@ -350,6 +350,11 @@ static int can_stm32_set_mode(const struct device *dev, enum can_mode mode)
|
|||
|
||||
LOG_DBG("Set mode %d", mode);
|
||||
|
||||
if ((mode & ~(CAN_MODE_LOOPBACK | CAN_MODE_LISTENONLY)) != 0) {
|
||||
LOG_ERR("unsupported mode: 0x%08x", mode);
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
k_mutex_lock(&data->inst_mutex, K_FOREVER);
|
||||
|
||||
if (cfg->phy != NULL) {
|
||||
|
@ -366,23 +371,18 @@ static int can_stm32_set_mode(const struct device *dev, enum can_mode mode)
|
|||
goto done;
|
||||
}
|
||||
|
||||
switch (mode) {
|
||||
case CAN_NORMAL_MODE:
|
||||
can->BTR &= ~(CAN_BTR_LBKM | CAN_BTR_SILM);
|
||||
break;
|
||||
case CAN_LOOPBACK_MODE:
|
||||
can->BTR &= ~(CAN_BTR_SILM);
|
||||
if ((mode & CAN_MODE_LOOPBACK) != 0) {
|
||||
/* Loopback mode */
|
||||
can->BTR |= CAN_BTR_LBKM;
|
||||
break;
|
||||
case CAN_SILENT_MODE:
|
||||
can->BTR &= ~(CAN_BTR_LBKM);
|
||||
} else {
|
||||
can->BTR &= ~CAN_BTR_LBKM;
|
||||
}
|
||||
|
||||
if ((mode & CAN_MODE_LISTENONLY) != 0) {
|
||||
/* Silent mode */
|
||||
can->BTR |= CAN_BTR_SILM;
|
||||
break;
|
||||
case CAN_SILENT_LOOPBACK_MODE:
|
||||
can->BTR |= CAN_BTR_LBKM | CAN_BTR_SILM;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
} else {
|
||||
can->BTR &= ~CAN_BTR_SILM;
|
||||
}
|
||||
|
||||
done:
|
||||
|
@ -568,7 +568,7 @@ static int can_stm32_init(const struct device *dev)
|
|||
return ret;
|
||||
}
|
||||
|
||||
ret = can_stm32_set_mode(dev, CAN_NORMAL_MODE);
|
||||
ret = can_stm32_set_mode(dev, CAN_MODE_NORMAL);
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue