drivers: can: remove CAN_BUS_UNKNOWN CAN controller state
The CAN_BUS_UNKNOWN CAN controller state is only used to indicate that the current CAN controller state could not be read. Remove it and change the signature of the can_get_state() API function to return an integer indicating success or failure. Signed-off-by: Henrik Brix Andersen <hebad@vestas.com>
This commit is contained in:
parent
b2190fd703
commit
2aed5a1237
15 changed files with 155 additions and 114 deletions
|
@ -81,21 +81,24 @@ static inline void z_vrfy_can_remove_rx_filter(const struct device *dev, int fil
|
||||||
#include <syscalls/can_remove_rx_filter_mrsh.c>
|
#include <syscalls/can_remove_rx_filter_mrsh.c>
|
||||||
|
|
||||||
static inline
|
static inline
|
||||||
enum can_state z_vrfy_can_get_state(const struct device *dev,
|
int z_vrfy_can_get_state(const struct device *dev, enum can_state *state,
|
||||||
struct can_bus_err_cnt *err_cnt)
|
struct can_bus_err_cnt *err_cnt)
|
||||||
{
|
{
|
||||||
|
|
||||||
Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_CAN));
|
Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_CAN));
|
||||||
|
|
||||||
if (err_cnt) {
|
if (state != NULL) {
|
||||||
Z_OOPS(Z_SYSCALL_MEMORY_WRITE(err_cnt, sizeof(err_cnt)));
|
Z_OOPS(Z_SYSCALL_MEMORY_WRITE(state, sizeof(enum can_state)));
|
||||||
}
|
}
|
||||||
|
|
||||||
return z_impl_can_get_state(dev, err_cnt);
|
if (err_cnt != NULL) {
|
||||||
|
Z_OOPS(Z_SYSCALL_MEMORY_WRITE(err_cnt, sizeof(struct can_bus_err_cnt)));
|
||||||
|
}
|
||||||
|
|
||||||
|
return z_impl_can_get_state(dev, state, err_cnt);
|
||||||
}
|
}
|
||||||
#include <syscalls/can_get_state_mrsh.c>
|
#include <syscalls/can_get_state_mrsh.c>
|
||||||
|
|
||||||
|
|
||||||
#ifndef CONFIG_CAN_AUTO_BUS_OFF_RECOVERY
|
#ifndef CONFIG_CAN_AUTO_BUS_OFF_RECOVERY
|
||||||
static inline int z_vrfy_can_recover(const struct device *dev,
|
static inline int z_vrfy_can_recover(const struct device *dev,
|
||||||
k_timeout_t timeout)
|
k_timeout_t timeout)
|
||||||
|
|
|
@ -212,17 +212,21 @@ int can_loopback_set_timing(const struct device *dev,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum can_state can_loopback_get_state(const struct device *dev,
|
static int can_loopback_get_state(const struct device *dev, enum can_state *state,
|
||||||
struct can_bus_err_cnt *err_cnt)
|
struct can_bus_err_cnt *err_cnt)
|
||||||
{
|
{
|
||||||
ARG_UNUSED(dev);
|
ARG_UNUSED(dev);
|
||||||
|
|
||||||
|
if (state != NULL) {
|
||||||
|
*state = CAN_ERROR_ACTIVE;
|
||||||
|
}
|
||||||
|
|
||||||
if (err_cnt) {
|
if (err_cnt) {
|
||||||
err_cnt->tx_err_cnt = 0;
|
err_cnt->tx_err_cnt = 0;
|
||||||
err_cnt->rx_err_cnt = 0;
|
err_cnt->rx_err_cnt = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return CAN_ERROR_ACTIVE;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef CONFIG_CAN_AUTO_BUS_OFF_RECOVERY
|
#ifndef CONFIG_CAN_AUTO_BUS_OFF_RECOVERY
|
||||||
|
|
|
@ -451,7 +451,7 @@ static void can_mcan_state_change_handler(const struct can_mcan_config *cfg,
|
||||||
const can_state_change_callback_t cb = data->state_change_cb;
|
const can_state_change_callback_t cb = data->state_change_cb;
|
||||||
void *cb_data = data->state_change_cb_data;
|
void *cb_data = data->state_change_cb_data;
|
||||||
|
|
||||||
state = can_mcan_get_state(cfg, &err_cnt);
|
(void)can_mcan_get_state(cfg, &state, &err_cnt);
|
||||||
|
|
||||||
if (cb != NULL) {
|
if (cb != NULL) {
|
||||||
cb(state, err_cnt, cb_data);
|
cb(state, err_cnt, cb_data);
|
||||||
|
@ -642,30 +642,32 @@ void can_mcan_line_1_isr(const struct can_mcan_config *cfg,
|
||||||
CAN_MCAN_IR_RF0L | CAN_MCAN_IR_RF1L));
|
CAN_MCAN_IR_RF0L | CAN_MCAN_IR_RF1L));
|
||||||
}
|
}
|
||||||
|
|
||||||
enum can_state can_mcan_get_state(const struct can_mcan_config *cfg,
|
int can_mcan_get_state(const struct can_mcan_config *cfg, enum can_state *state,
|
||||||
struct can_bus_err_cnt *err_cnt)
|
struct can_bus_err_cnt *err_cnt)
|
||||||
{
|
{
|
||||||
struct can_mcan_reg *can = cfg->can;
|
struct can_mcan_reg *can = cfg->can;
|
||||||
|
|
||||||
|
if (state != NULL) {
|
||||||
|
if (can->psr & CAN_MCAN_PSR_BO) {
|
||||||
|
*state = CAN_BUS_OFF;
|
||||||
|
} else if (can->psr & CAN_MCAN_PSR_EP) {
|
||||||
|
*state = CAN_ERROR_PASSIVE;
|
||||||
|
} else if (can->psr & CAN_MCAN_PSR_EW) {
|
||||||
|
*state = CAN_ERROR_WARNING;
|
||||||
|
} else {
|
||||||
|
*state = CAN_ERROR_ACTIVE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (err_cnt != NULL) {
|
||||||
err_cnt->rx_err_cnt = (can->ecr & CAN_MCAN_ECR_TEC_MSK) <<
|
err_cnt->rx_err_cnt = (can->ecr & CAN_MCAN_ECR_TEC_MSK) <<
|
||||||
CAN_MCAN_ECR_TEC_POS;
|
CAN_MCAN_ECR_TEC_POS;
|
||||||
|
|
||||||
err_cnt->tx_err_cnt = (can->ecr & CAN_MCAN_ECR_REC_MSK) <<
|
err_cnt->tx_err_cnt = (can->ecr & CAN_MCAN_ECR_REC_MSK) <<
|
||||||
CAN_MCAN_ECR_REC_POS;
|
CAN_MCAN_ECR_REC_POS;
|
||||||
|
|
||||||
if (can->psr & CAN_MCAN_PSR_BO) {
|
|
||||||
return CAN_BUS_OFF;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (can->psr & CAN_MCAN_PSR_EP) {
|
return 0;
|
||||||
return CAN_ERROR_PASSIVE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (can->psr & CAN_MCAN_PSR_EW) {
|
|
||||||
return CAN_ERROR_WARNING;
|
|
||||||
}
|
|
||||||
|
|
||||||
return CAN_ERROR_ACTIVE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef CONFIG_CAN_AUTO_BUS_OFF_RECOVERY
|
#ifndef CONFIG_CAN_AUTO_BUS_OFF_RECOVERY
|
||||||
|
|
|
@ -238,7 +238,7 @@ int can_mcan_add_rx_filter(struct can_mcan_data *data,
|
||||||
void can_mcan_remove_rx_filter(struct can_mcan_data *data,
|
void can_mcan_remove_rx_filter(struct can_mcan_data *data,
|
||||||
struct can_mcan_msg_sram *msg_ram, int filter_id);
|
struct can_mcan_msg_sram *msg_ram, int filter_id);
|
||||||
|
|
||||||
enum can_state can_mcan_get_state(const struct can_mcan_config *cfg,
|
int can_mcan_get_state(const struct can_mcan_config *cfg, enum can_state *state,
|
||||||
struct can_bus_err_cnt *err_cnt);
|
struct can_bus_err_cnt *err_cnt);
|
||||||
|
|
||||||
#endif /* ZEPHYR_DRIVERS_CAN_MCAN_H_ */
|
#endif /* ZEPHYR_DRIVERS_CAN_MCAN_H_ */
|
||||||
|
|
|
@ -649,7 +649,7 @@ static void mcp2515_tx_done(const struct device *dev, uint8_t tx_idx)
|
||||||
k_sem_give(&dev_data->tx_sem);
|
k_sem_give(&dev_data->tx_sem);
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum can_state mcp2515_get_state(const struct device *dev,
|
static int mcp2515_get_state(const struct device *dev, enum can_state *state,
|
||||||
struct can_bus_err_cnt *err_cnt)
|
struct can_bus_err_cnt *err_cnt)
|
||||||
{
|
{
|
||||||
uint8_t eflg;
|
uint8_t eflg;
|
||||||
|
@ -659,34 +659,34 @@ static enum can_state mcp2515_get_state(const struct device *dev,
|
||||||
ret = mcp2515_cmd_read_reg(dev, MCP2515_ADDR_EFLG, &eflg, sizeof(eflg));
|
ret = mcp2515_cmd_read_reg(dev, MCP2515_ADDR_EFLG, &eflg, sizeof(eflg));
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
LOG_ERR("Failed to read error register [%d]", ret);
|
LOG_ERR("Failed to read error register [%d]", ret);
|
||||||
return CAN_BUS_UNKNOWN;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (err_cnt) {
|
if (state != NULL) {
|
||||||
|
if (eflg & MCP2515_EFLG_TXBO) {
|
||||||
|
*state = CAN_BUS_OFF;
|
||||||
|
} else if ((eflg & MCP2515_EFLG_RXEP) || (eflg & MCP2515_EFLG_TXEP)) {
|
||||||
|
*state = CAN_ERROR_PASSIVE;
|
||||||
|
} else if (eflg & MCP2515_EFLG_EWARN) {
|
||||||
|
*state = CAN_ERROR_WARNING;
|
||||||
|
} else {
|
||||||
|
*state = CAN_ERROR_ACTIVE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (err_cnt != NULL) {
|
||||||
ret = mcp2515_cmd_read_reg(dev, MCP2515_ADDR_TEC, err_cnt_buf,
|
ret = mcp2515_cmd_read_reg(dev, MCP2515_ADDR_TEC, err_cnt_buf,
|
||||||
sizeof(err_cnt_buf));
|
sizeof(err_cnt_buf));
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
LOG_ERR("Failed to read error counters [%d]", ret);
|
LOG_ERR("Failed to read error counters [%d]", ret);
|
||||||
return CAN_BUS_UNKNOWN;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
err_cnt->tx_err_cnt = err_cnt_buf[0];
|
err_cnt->tx_err_cnt = err_cnt_buf[0];
|
||||||
err_cnt->rx_err_cnt = err_cnt_buf[1];
|
err_cnt->rx_err_cnt = err_cnt_buf[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (eflg & MCP2515_EFLG_TXBO) {
|
return 0;
|
||||||
return CAN_BUS_OFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((eflg & MCP2515_EFLG_RXEP) || (eflg & MCP2515_EFLG_TXEP)) {
|
|
||||||
return CAN_ERROR_PASSIVE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (eflg & MCP2515_EFLG_EWARN) {
|
|
||||||
return CAN_ERROR_WARNING;
|
|
||||||
}
|
|
||||||
|
|
||||||
return CAN_ERROR_ACTIVE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mcp2515_handle_errors(const struct device *dev)
|
static void mcp2515_handle_errors(const struct device *dev)
|
||||||
|
@ -696,8 +696,13 @@ static void mcp2515_handle_errors(const struct device *dev)
|
||||||
void *state_change_cb_data = dev_data->state_change_cb_data;
|
void *state_change_cb_data = dev_data->state_change_cb_data;
|
||||||
enum can_state state;
|
enum can_state state;
|
||||||
struct can_bus_err_cnt err_cnt;
|
struct can_bus_err_cnt err_cnt;
|
||||||
|
int err;
|
||||||
|
|
||||||
state = mcp2515_get_state(dev, state_change_cb ? &err_cnt : NULL);
|
err = mcp2515_get_state(dev, &state, state_change_cb ? &err_cnt : NULL);
|
||||||
|
if (err != 0) {
|
||||||
|
LOG_ERR("Failed to get CAN controller state [%d]", err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (state_change_cb && dev_data->old_state != state) {
|
if (state_change_cb && dev_data->old_state != state) {
|
||||||
dev_data->old_state = state;
|
dev_data->old_state = state;
|
||||||
|
|
|
@ -316,32 +316,33 @@ static int mcux_get_tx_alloc(struct mcux_flexcan_data *data)
|
||||||
return alloc >= MCUX_FLEXCAN_MAX_TX ? -1 : alloc;
|
return alloc >= MCUX_FLEXCAN_MAX_TX ? -1 : alloc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum can_state mcux_flexcan_get_state(const struct device *dev,
|
static int mcux_flexcan_get_state(const struct device *dev, enum can_state *state,
|
||||||
struct can_bus_err_cnt *err_cnt)
|
struct can_bus_err_cnt *err_cnt)
|
||||||
{
|
{
|
||||||
const struct mcux_flexcan_config *config = dev->config;
|
const struct mcux_flexcan_config *config = dev->config;
|
||||||
uint64_t status_flags;
|
uint64_t status_flags;
|
||||||
|
|
||||||
|
if (state != NULL) {
|
||||||
|
status_flags = FLEXCAN_GetStatusFlags(config->base);
|
||||||
|
|
||||||
|
if ((status_flags & CAN_ESR1_FLTCONF(2)) != 0U) {
|
||||||
|
*state = CAN_BUS_OFF;
|
||||||
|
} else if ((status_flags & CAN_ESR1_FLTCONF(1)) != 0U) {
|
||||||
|
*state = CAN_ERROR_PASSIVE;
|
||||||
|
} else if ((status_flags &
|
||||||
|
(kFLEXCAN_TxErrorWarningFlag | kFLEXCAN_RxErrorWarningFlag)) != 0) {
|
||||||
|
*state = CAN_ERROR_WARNING;
|
||||||
|
} else {
|
||||||
|
*state = CAN_ERROR_ACTIVE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (err_cnt != NULL) {
|
if (err_cnt != NULL) {
|
||||||
FLEXCAN_GetBusErrCount(config->base, &err_cnt->tx_err_cnt,
|
FLEXCAN_GetBusErrCount(config->base, &err_cnt->tx_err_cnt,
|
||||||
&err_cnt->rx_err_cnt);
|
&err_cnt->rx_err_cnt);
|
||||||
}
|
}
|
||||||
|
|
||||||
status_flags = FLEXCAN_GetStatusFlags(config->base);
|
return 0;
|
||||||
|
|
||||||
if ((status_flags & CAN_ESR1_FLTCONF(2)) != 0U) {
|
|
||||||
return CAN_BUS_OFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((status_flags & CAN_ESR1_FLTCONF(1)) != 0U) {
|
|
||||||
return CAN_ERROR_PASSIVE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((status_flags & (kFLEXCAN_TxErrorWarningFlag | kFLEXCAN_RxErrorWarningFlag)) != 0) {
|
|
||||||
return CAN_ERROR_WARNING;
|
|
||||||
}
|
|
||||||
|
|
||||||
return CAN_ERROR_ACTIVE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mcux_flexcan_send(const struct device *dev,
|
static int mcux_flexcan_send(const struct device *dev,
|
||||||
|
@ -352,6 +353,7 @@ static int mcux_flexcan_send(const struct device *dev,
|
||||||
const struct mcux_flexcan_config *config = dev->config;
|
const struct mcux_flexcan_config *config = dev->config;
|
||||||
struct mcux_flexcan_data *data = dev->data;
|
struct mcux_flexcan_data *data = dev->data;
|
||||||
flexcan_mb_transfer_t xfer;
|
flexcan_mb_transfer_t xfer;
|
||||||
|
enum can_state state;
|
||||||
status_t status;
|
status_t status;
|
||||||
int alloc;
|
int alloc;
|
||||||
|
|
||||||
|
@ -360,7 +362,8 @@ static int mcux_flexcan_send(const struct device *dev,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mcux_flexcan_get_state(dev, NULL) == CAN_BUS_OFF) {
|
(void)mcux_flexcan_get_state(dev, &state, NULL);
|
||||||
|
if (state == CAN_BUS_OFF) {
|
||||||
LOG_DBG("Transmit failed, bus-off");
|
LOG_DBG("Transmit failed, bus-off");
|
||||||
return -ENETDOWN;
|
return -ENETDOWN;
|
||||||
}
|
}
|
||||||
|
@ -470,10 +473,12 @@ static void mcux_flexcan_set_state_change_callback(const struct device *dev,
|
||||||
int mcux_flexcan_recover(const struct device *dev, k_timeout_t timeout)
|
int mcux_flexcan_recover(const struct device *dev, k_timeout_t timeout)
|
||||||
{
|
{
|
||||||
const struct mcux_flexcan_config *config = dev->config;
|
const struct mcux_flexcan_config *config = dev->config;
|
||||||
int ret = 0;
|
enum can_state state;
|
||||||
uint64_t start_time;
|
uint64_t start_time;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
if (mcux_flexcan_get_state(dev, NULL) != CAN_BUS_OFF) {
|
(void)mcux_flexcan_get_state(dev, &state, NULL);
|
||||||
|
if (state != CAN_BUS_OFF) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -481,11 +486,15 @@ int mcux_flexcan_recover(const struct device *dev, k_timeout_t timeout)
|
||||||
config->base->CTRL1 &= ~CAN_CTRL1_BOFFREC_MASK;
|
config->base->CTRL1 &= ~CAN_CTRL1_BOFFREC_MASK;
|
||||||
|
|
||||||
if (!K_TIMEOUT_EQ(timeout, K_NO_WAIT)) {
|
if (!K_TIMEOUT_EQ(timeout, K_NO_WAIT)) {
|
||||||
while (mcux_flexcan_get_state(dev, NULL) == CAN_BUS_OFF) {
|
(void)mcux_flexcan_get_state(dev, &state, NULL);
|
||||||
|
|
||||||
|
while (state == CAN_BUS_OFF) {
|
||||||
if (!K_TIMEOUT_EQ(timeout, K_FOREVER) &&
|
if (!K_TIMEOUT_EQ(timeout, K_FOREVER) &&
|
||||||
k_uptime_ticks() - start_time >= timeout.ticks) {
|
k_uptime_ticks() - start_time >= timeout.ticks) {
|
||||||
ret = -EAGAIN;
|
ret = -EAGAIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
(void)mcux_flexcan_get_state(dev, &state, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -556,7 +565,7 @@ static inline void mcux_flexcan_transfer_error_status(const struct device *dev,
|
||||||
LOG_DBG("RX CRC error (error 0x%016llx)", error);
|
LOG_DBG("RX CRC error (error 0x%016llx)", error);
|
||||||
}
|
}
|
||||||
|
|
||||||
state = mcux_flexcan_get_state(dev, &err_cnt);
|
(void)mcux_flexcan_get_state(dev, &state, &err_cnt);
|
||||||
if (data->state != state) {
|
if (data->state != state) {
|
||||||
data->state = state;
|
data->state = state;
|
||||||
|
|
||||||
|
@ -745,7 +754,8 @@ static int mcux_flexcan_init(const struct device *dev)
|
||||||
#ifndef CONFIG_CAN_AUTO_BUS_OFF_RECOVERY
|
#ifndef CONFIG_CAN_AUTO_BUS_OFF_RECOVERY
|
||||||
config->base->CTRL1 |= CAN_CTRL1_BOFFREC_MASK;
|
config->base->CTRL1 |= CAN_CTRL1_BOFFREC_MASK;
|
||||||
#endif /* CONFIG_CAN_AUTO_BUS_OFF_RECOVERY */
|
#endif /* CONFIG_CAN_AUTO_BUS_OFF_RECOVERY */
|
||||||
data->state = mcux_flexcan_get_state(dev, NULL);
|
|
||||||
|
(void)mcux_flexcan_get_state(dev, &data->state, NULL);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,12 +72,12 @@ static void mcux_mcan_remove_rx_filter(const struct device *dev, int filter_id)
|
||||||
can_mcan_remove_rx_filter(&data->mcan, &data->msg_ram, filter_id);
|
can_mcan_remove_rx_filter(&data->mcan, &data->msg_ram, filter_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum can_state mcux_mcan_get_state(const struct device *dev,
|
static int mcux_mcan_get_state(const struct device *dev, enum can_state *state,
|
||||||
struct can_bus_err_cnt *err_cnt)
|
struct can_bus_err_cnt *err_cnt)
|
||||||
{
|
{
|
||||||
const struct mcux_mcan_config *config = dev->config;
|
const struct mcux_mcan_config *config = dev->config;
|
||||||
|
|
||||||
return can_mcan_get_state(&config->mcan, err_cnt);
|
return can_mcan_get_state(&config->mcan, state, err_cnt);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mcux_mcan_set_state_change_callback(const struct device *dev,
|
static void mcux_mcan_set_state_change_callback(const struct device *dev,
|
||||||
|
|
|
@ -671,16 +671,21 @@ static void can_rcar_set_state_change_callback(const struct device *dev,
|
||||||
data->state_change_cb_data = user_data;
|
data->state_change_cb_data = user_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum can_state can_rcar_get_state(const struct device *dev,
|
static int can_rcar_get_state(const struct device *dev, enum can_state *state,
|
||||||
struct can_bus_err_cnt *err_cnt)
|
struct can_bus_err_cnt *err_cnt)
|
||||||
{
|
{
|
||||||
const struct can_rcar_cfg *config = DEV_CAN_CFG(dev);
|
const struct can_rcar_cfg *config = DEV_CAN_CFG(dev);
|
||||||
struct can_rcar_data *data = DEV_CAN_DATA(dev);
|
struct can_rcar_data *data = DEV_CAN_DATA(dev);
|
||||||
|
|
||||||
|
if (state != NULL) {
|
||||||
|
*state = data->state;
|
||||||
|
}
|
||||||
|
|
||||||
if (err_cnt != NULL) {
|
if (err_cnt != NULL) {
|
||||||
can_rcar_get_error_count(config, err_cnt);
|
can_rcar_get_error_count(config, err_cnt);
|
||||||
}
|
}
|
||||||
return data->state;
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef CONFIG_CAN_AUTO_BUS_OFF_RECOVERY
|
#ifndef CONFIG_CAN_AUTO_BUS_OFF_RECOVERY
|
||||||
|
|
|
@ -71,12 +71,13 @@ static int can_sam_init(const struct device *dev)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum can_state can_sam_get_state(const struct device *dev, struct can_bus_err_cnt *err_cnt)
|
static int can_sam_get_state(const struct device *dev, enum can_state *state,
|
||||||
|
struct can_bus_err_cnt *err_cnt)
|
||||||
{
|
{
|
||||||
const struct can_sam_config *cfg = dev->config;
|
const struct can_sam_config *cfg = dev->config;
|
||||||
const struct can_mcan_config *mcan_cfg = &cfg->mcan_cfg;
|
const struct can_mcan_config *mcan_cfg = &cfg->mcan_cfg;
|
||||||
|
|
||||||
return can_mcan_get_state(mcan_cfg, err_cnt);
|
return can_mcan_get_state(mcan_cfg, state, err_cnt);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int can_sam_send(const struct device *dev, const struct zcan_frame *frame,
|
static int can_sam_send(const struct device *dev, const struct zcan_frame *frame,
|
||||||
|
|
|
@ -551,33 +551,32 @@ static void can_stm32_set_state_change_callback(const struct device *dev,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum can_state can_stm32_get_state(const struct device *dev,
|
static int can_stm32_get_state(const struct device *dev, enum can_state *state,
|
||||||
struct can_bus_err_cnt *err_cnt)
|
struct can_bus_err_cnt *err_cnt)
|
||||||
{
|
{
|
||||||
const struct can_stm32_config *cfg = dev->config;
|
const struct can_stm32_config *cfg = dev->config;
|
||||||
CAN_TypeDef *can = cfg->can;
|
CAN_TypeDef *can = cfg->can;
|
||||||
|
|
||||||
if (err_cnt) {
|
if (state != NULL) {
|
||||||
|
if (can->ESR & CAN_ESR_BOFF) {
|
||||||
|
*state = CAN_BUS_OFF;
|
||||||
|
} else if (can->ESR & CAN_ESR_EPVF) {
|
||||||
|
*state = CAN_ERROR_PASSIVE;
|
||||||
|
} else if (can->ESR & CAN_ESR_EWGF) {
|
||||||
|
*state = CAN_ERROR_WARNING;
|
||||||
|
} else {
|
||||||
|
*state = CAN_ERROR_ACTIVE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (err_cnt != NULL) {
|
||||||
err_cnt->tx_err_cnt =
|
err_cnt->tx_err_cnt =
|
||||||
((can->ESR & CAN_ESR_TEC) >> CAN_ESR_TEC_Pos);
|
((can->ESR & CAN_ESR_TEC) >> CAN_ESR_TEC_Pos);
|
||||||
err_cnt->rx_err_cnt =
|
err_cnt->rx_err_cnt =
|
||||||
((can->ESR & CAN_ESR_REC) >> CAN_ESR_REC_Pos);
|
((can->ESR & CAN_ESR_REC) >> CAN_ESR_REC_Pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (can->ESR & CAN_ESR_BOFF) {
|
return 0;
|
||||||
return CAN_BUS_OFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (can->ESR & CAN_ESR_EPVF) {
|
|
||||||
return CAN_ERROR_PASSIVE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (can->ESR & CAN_ESR_EWGF) {
|
|
||||||
return CAN_ERROR_WARNING;
|
|
||||||
}
|
|
||||||
|
|
||||||
return CAN_ERROR_ACTIVE;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef CONFIG_CAN_AUTO_BUS_OFF_RECOVERY
|
#ifndef CONFIG_CAN_AUTO_BUS_OFF_RECOVERY
|
||||||
|
|
|
@ -90,13 +90,13 @@ static int can_stm32fd_init(const struct device *dev)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum can_state can_stm32fd_get_state(const struct device *dev,
|
static int can_stm32fd_get_state(const struct device *dev, enum can_state *state,
|
||||||
struct can_bus_err_cnt *err_cnt)
|
struct can_bus_err_cnt *err_cnt)
|
||||||
{
|
{
|
||||||
const struct can_stm32fd_config *cfg = dev->config;
|
const struct can_stm32fd_config *cfg = dev->config;
|
||||||
const struct can_mcan_config *mcan_cfg = &cfg->mcan_cfg;
|
const struct can_mcan_config *mcan_cfg = &cfg->mcan_cfg;
|
||||||
|
|
||||||
return can_mcan_get_state(mcan_cfg, err_cnt);
|
return can_mcan_get_state(mcan_cfg, state, err_cnt);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int can_stm32fd_send(const struct device *dev, const struct zcan_frame *frame,
|
static int can_stm32fd_send(const struct device *dev, const struct zcan_frame *frame,
|
||||||
|
|
|
@ -120,12 +120,12 @@ static int can_stm32h7_init(const struct device *dev)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum can_state can_stm32h7_get_state(const struct device *dev,
|
static int can_stm32h7_get_state(const struct device *dev, enum can_state *state,
|
||||||
struct can_bus_err_cnt *err_cnt)
|
struct can_bus_err_cnt *err_cnt)
|
||||||
{
|
{
|
||||||
const struct can_stm32h7_config *cfg = dev->config;
|
const struct can_stm32h7_config *cfg = dev->config;
|
||||||
|
|
||||||
return can_mcan_get_state(&cfg->mcan_cfg, err_cnt);
|
return can_mcan_get_state(&cfg->mcan_cfg, state, err_cnt);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int can_stm32h7_send(const struct device *dev,
|
static int can_stm32h7_send(const struct device *dev,
|
||||||
|
|
|
@ -104,8 +104,6 @@ enum can_state {
|
||||||
CAN_ERROR_PASSIVE,
|
CAN_ERROR_PASSIVE,
|
||||||
/** Bus-off state (RX/TX error count >= 256). */
|
/** Bus-off state (RX/TX error count >= 256). */
|
||||||
CAN_BUS_OFF,
|
CAN_BUS_OFF,
|
||||||
/** Bus state unknown. */
|
|
||||||
CAN_BUS_UNKNOWN
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -347,7 +345,7 @@ typedef int (*can_recover_t)(const struct device *dev, k_timeout_t timeout);
|
||||||
* @brief Callback API upon getting the CAN controller state
|
* @brief Callback API upon getting the CAN controller state
|
||||||
* See @a can_get_state() for argument description
|
* See @a can_get_state() for argument description
|
||||||
*/
|
*/
|
||||||
typedef enum can_state (*can_get_state_t)(const struct device *dev,
|
typedef int (*can_get_state_t)(const struct device *dev, enum can_state *state,
|
||||||
struct can_bus_err_cnt *err_cnt);
|
struct can_bus_err_cnt *err_cnt);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -826,19 +824,21 @@ static inline int z_impl_can_get_max_filters(const struct device *dev, enum can_
|
||||||
* controller.
|
* controller.
|
||||||
*
|
*
|
||||||
* @param dev Pointer to the device structure for the driver instance.
|
* @param dev Pointer to the device structure for the driver instance.
|
||||||
|
* @param[out] state Pointer to the state destination enum or NULL.
|
||||||
* @param[out] err_cnt Pointer to the err_cnt destination structure or NULL.
|
* @param[out] err_cnt Pointer to the err_cnt destination structure or NULL.
|
||||||
*
|
*
|
||||||
* @retval state
|
* @retval 0 If successful.
|
||||||
|
* @retval -EIO General input/output error, failed to get state.
|
||||||
*/
|
*/
|
||||||
__syscall enum can_state can_get_state(const struct device *dev,
|
__syscall int can_get_state(const struct device *dev, enum can_state *state,
|
||||||
struct can_bus_err_cnt *err_cnt);
|
struct can_bus_err_cnt *err_cnt);
|
||||||
|
|
||||||
static inline enum can_state z_impl_can_get_state(const struct device *dev,
|
static inline int z_impl_can_get_state(const struct device *dev, enum can_state *state,
|
||||||
struct can_bus_err_cnt *err_cnt)
|
struct can_bus_err_cnt *err_cnt)
|
||||||
{
|
{
|
||||||
const struct can_driver_api *api = (const struct can_driver_api *)dev->api;
|
const struct can_driver_api *api = (const struct can_driver_api *)dev->api;
|
||||||
|
|
||||||
return api->get_state(dev, err_cnt);
|
return api->get_state(dev, state, err_cnt);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -406,6 +406,7 @@ void CO_CANverifyErrors(CO_CANmodule_t *CANmodule)
|
||||||
enum can_state state;
|
enum can_state state;
|
||||||
uint8_t rx_overflows;
|
uint8_t rx_overflows;
|
||||||
uint32_t errors;
|
uint32_t errors;
|
||||||
|
int err;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* TODO: Zephyr lacks an API for reading the rx mailbox
|
* TODO: Zephyr lacks an API for reading the rx mailbox
|
||||||
|
@ -413,7 +414,11 @@ void CO_CANverifyErrors(CO_CANmodule_t *CANmodule)
|
||||||
*/
|
*/
|
||||||
rx_overflows = 0;
|
rx_overflows = 0;
|
||||||
|
|
||||||
state = can_get_state(CANmodule->dev, &err_cnt);
|
err = can_get_state(CANmodule->dev, &state, &err_cnt);
|
||||||
|
if (err != 0) {
|
||||||
|
LOG_ERR("failed to get CAN controller state (err %d)", err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
errors = ((uint32_t)err_cnt.tx_err_cnt << 16) |
|
errors = ((uint32_t)err_cnt.tx_err_cnt << 16) |
|
||||||
((uint32_t)err_cnt.rx_err_cnt << 8) |
|
((uint32_t)err_cnt.rx_err_cnt << 8) |
|
||||||
|
|
|
@ -127,9 +127,16 @@ void poll_state_thread(void *unused1, void *unused2, void *unused3)
|
||||||
struct can_bus_err_cnt err_cnt_prev = {0, 0};
|
struct can_bus_err_cnt err_cnt_prev = {0, 0};
|
||||||
enum can_state state_prev = CAN_ERROR_ACTIVE;
|
enum can_state state_prev = CAN_ERROR_ACTIVE;
|
||||||
enum can_state state;
|
enum can_state state;
|
||||||
|
int err;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
state = can_get_state(can_dev, &err_cnt);
|
err = can_get_state(can_dev, &state, &err_cnt);
|
||||||
|
if (err != 0) {
|
||||||
|
printk("Failed to get CAN controller state: %d", err);
|
||||||
|
k_sleep(K_MSEC(100));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (err_cnt.tx_err_cnt != err_cnt_prev.tx_err_cnt ||
|
if (err_cnt.tx_err_cnt != err_cnt_prev.tx_err_cnt ||
|
||||||
err_cnt.rx_err_cnt != err_cnt_prev.rx_err_cnt ||
|
err_cnt.rx_err_cnt != err_cnt_prev.rx_err_cnt ||
|
||||||
state_prev != state) {
|
state_prev != state) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue