drivers: can: use flags fields for can_frame and can_filter structs
The can_frame and can_filter structs support a number of different flags (standard/extended CAN ID type, Remote Transmission Request, CAN-FD format, Bit Rate Switch, ...). Each of these flags is represented as a discrete bit in the given structure. This design pattern requires every user of these structs to initialize all of these flags to either 0 or 1, which does not scale well for future flag additions. Some of these flags have associated enumerations to be used for assignment, some do not. CAN drivers and protocols tend to rely on the logical value of the flag instead of using the enumeration, leading to a very fragile API. The enumerations are used inconsistently between the can_frame and can_filter structures, which further complicates the API. Instead, convert these flags to bitfields with separate flag definitions for the can_frame and can_filter structures. This API allows for future extensions without having to revisit existing users of the two structures. Furthermore, this allows driver to easily check for unsupported flags in the respective API calls. As this change leads to the "id_mask" field of the can_filter to be the only mask present in that structure, rename it to "mask" for simplicity. Fixes: #50776 Signed-off-by: Henrik Brix Andersen <hebad@vestas.com>
This commit is contained in:
parent
a9c7c58345
commit
f8a88cdb27
29 changed files with 661 additions and 626 deletions
|
@ -129,12 +129,12 @@ static inline int z_vrfy_can_set_bitrate_data(const struct device *dev,
|
|||
|
||||
#endif /* CONFIG_CAN_FD_MODE */
|
||||
|
||||
static inline int z_vrfy_can_get_max_filters(const struct device *dev, enum can_ide id_type)
|
||||
static inline int z_vrfy_can_get_max_filters(const struct device *dev, bool ide)
|
||||
{
|
||||
/* Optional API function */
|
||||
Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_CAN));
|
||||
|
||||
return z_impl_can_get_max_filters(dev, id_type);
|
||||
return z_impl_can_get_max_filters(dev, ide);
|
||||
}
|
||||
#include <syscalls/can_get_max_filters_mrsh.c>
|
||||
|
||||
|
|
|
@ -33,11 +33,14 @@ struct can_loopback_filter {
|
|||
struct can_loopback_data {
|
||||
struct can_loopback_filter filters[CONFIG_CAN_MAX_FILTER];
|
||||
struct k_mutex mtx;
|
||||
bool loopback;
|
||||
struct k_msgq tx_msgq;
|
||||
char msgq_buffer[CONFIG_CAN_LOOPBACK_TX_MSGQ_SIZE * sizeof(struct can_loopback_frame)];
|
||||
struct k_thread tx_thread_data;
|
||||
bool started;
|
||||
bool loopback;
|
||||
#ifdef CONFIG_CAN_FD_MODE
|
||||
bool fd;
|
||||
#endif /* CONFIG_CAN_FD_MODE */
|
||||
|
||||
K_KERNEL_STACK_MEMBER(tx_thread_stack,
|
||||
CONFIG_CAN_LOOPBACK_TX_THREAD_STACK_SIZE);
|
||||
|
@ -51,9 +54,8 @@ static void dispatch_frame(const struct device *dev,
|
|||
|
||||
LOG_DBG("Receiving %d bytes. Id: 0x%x, ID type: %s %s",
|
||||
frame->dlc, frame->id,
|
||||
frame->id_type == CAN_STANDARD_IDENTIFIER ?
|
||||
"standard" : "extended",
|
||||
frame->rtr == CAN_DATAFRAME ? "" : ", RTR frame");
|
||||
(frame->flags & CAN_FRAME_IDE) != 0 ? "extended" : "standard",
|
||||
(frame->flags & CAN_FRAME_RTR) != 0 ? ", RTR frame" : "");
|
||||
|
||||
filter->rx_cb(dev, &frame_tmp, filter->cb_arg);
|
||||
}
|
||||
|
@ -99,15 +101,29 @@ static int can_loopback_send(const struct device *dev,
|
|||
|
||||
LOG_DBG("Sending %d bytes on %s. Id: 0x%x, ID type: %s %s",
|
||||
frame->dlc, dev->name, frame->id,
|
||||
frame->id_type == CAN_STANDARD_IDENTIFIER ?
|
||||
"standard" : "extended",
|
||||
frame->rtr == CAN_DATAFRAME ? "" : ", RTR frame");
|
||||
(frame->flags & CAN_FRAME_IDE) != 0 ? "extended" : "standard",
|
||||
(frame->flags & CAN_FRAME_RTR) != 0 ? ", RTR frame" : "");
|
||||
|
||||
#ifdef CONFIG_CAN_FD_MODE
|
||||
if (frame->fd != 0) {
|
||||
if ((frame->flags & ~(CAN_FRAME_IDE | CAN_FRAME_RTR |
|
||||
CAN_FRAME_FDF | CAN_FRAME_BRS)) != 0) {
|
||||
LOG_ERR("unsupported CAN frame flags 0x%02x", frame->flags);
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
if ((frame->flags & CAN_FRAME_FDF) != 0) {
|
||||
if (!data->fd) {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
max_dlc = CANFD_MAX_DLC;
|
||||
}
|
||||
#endif /* CONFIG_CAN_FD_MODE */
|
||||
#else /* CONFIG_CAN_FD_MODE */
|
||||
if ((frame->flags & ~(CAN_FRAME_IDE | CAN_FRAME_RTR)) != 0) {
|
||||
LOG_ERR("unsupported CAN frame flags 0x%02x", frame->flags);
|
||||
return -ENOTSUP;
|
||||
}
|
||||
#endif /* !CONFIG_CAN_FD_MODE */
|
||||
|
||||
if (frame->dlc > max_dlc) {
|
||||
LOG_ERR("DLC of %d exceeds maximum (%d)", frame->dlc, max_dlc);
|
||||
|
@ -150,14 +166,12 @@ static int can_loopback_add_rx_filter(const struct device *dev, can_rx_callback_
|
|||
struct can_loopback_filter *loopback_filter;
|
||||
int filter_id;
|
||||
|
||||
LOG_DBG("Setting filter ID: 0x%x, mask: 0x%x", filter->id,
|
||||
filter->id_mask);
|
||||
LOG_DBG("Filter type: %s ID %s mask",
|
||||
filter->id_type == CAN_STANDARD_IDENTIFIER ?
|
||||
"standard" : "extended",
|
||||
((filter->id_type && (filter->id_mask == CAN_STD_ID_MASK)) ||
|
||||
(!filter->id_type && (filter->id_mask == CAN_EXT_ID_MASK))) ?
|
||||
"with" : "without");
|
||||
LOG_DBG("Setting filter ID: 0x%x, mask: 0x%x", filter->id, filter->mask);
|
||||
|
||||
if ((filter->flags & ~(CAN_FILTER_IDE | CAN_FILTER_DATA | CAN_FILTER_RTR)) != 0) {
|
||||
LOG_ERR("unsupported CAN filter flags 0x%02x", filter->flags);
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
k_mutex_lock(&data->mtx, K_FOREVER);
|
||||
filter_id = get_free_filter(data->filters);
|
||||
|
@ -242,6 +256,8 @@ static int can_loopback_set_mode(const struct device *dev, can_mode_t mode)
|
|||
LOG_ERR("unsupported mode: 0x%08x", mode);
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
data->fd = (mode & CAN_MODE_FD) != 0;
|
||||
#else
|
||||
if ((mode & ~(CAN_MODE_LOOPBACK)) != 0) {
|
||||
LOG_ERR("unsupported mode: 0x%08x", mode);
|
||||
|
@ -249,7 +265,8 @@ static int can_loopback_set_mode(const struct device *dev, can_mode_t mode)
|
|||
}
|
||||
#endif /* CONFIG_CAN_FD_MODE */
|
||||
|
||||
data->loopback = (mode & CAN_MODE_LOOPBACK) != 0 ? 1 : 0;
|
||||
data->loopback = (mode & CAN_MODE_LOOPBACK) != 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -335,9 +352,9 @@ static int can_loopback_get_core_clock(const struct device *dev, uint32_t *rate)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int can_loopback_get_max_filters(const struct device *dev, enum can_ide id_type)
|
||||
static int can_loopback_get_max_filters(const struct device *dev, bool ide)
|
||||
{
|
||||
ARG_UNUSED(id_type);
|
||||
ARG_UNUSED(ide);
|
||||
|
||||
return CONFIG_CAN_MAX_FILTER;
|
||||
}
|
||||
|
|
|
@ -21,12 +21,6 @@ LOG_MODULE_REGISTER(can_mcan, CONFIG_CAN_LOG_LEVEL);
|
|||
#define CAN_INIT_TIMEOUT (100)
|
||||
#define CAN_DIV_CEIL(val, div) (((val) + (div) - 1) / (div))
|
||||
|
||||
#ifdef CONFIG_CAN_FD_MODE
|
||||
#define MCAN_MAX_DLC CANFD_MAX_DLC
|
||||
#else
|
||||
#define MCAN_MAX_DLC CAN_MAX_DLC
|
||||
#endif
|
||||
|
||||
static void memcpy32_volatile(volatile void *dst_, const volatile void *src_,
|
||||
size_t len)
|
||||
{
|
||||
|
@ -618,7 +612,7 @@ static void can_mcan_get_message(const struct device *dev,
|
|||
{
|
||||
struct can_mcan_data *data = dev->data;
|
||||
uint32_t get_idx, filt_idx;
|
||||
struct can_frame frame;
|
||||
struct can_frame frame = {0};
|
||||
can_rx_callback_t cb;
|
||||
int data_length;
|
||||
void *cb_arg;
|
||||
|
@ -636,18 +630,20 @@ static void can_mcan_get_message(const struct device *dev,
|
|||
memcpy32_volatile(&hdr, &fifo[get_idx].hdr,
|
||||
sizeof(struct can_mcan_rx_fifo_hdr));
|
||||
|
||||
if (hdr.xtd) {
|
||||
frame.id = hdr.ext_id;
|
||||
} else {
|
||||
frame.id = hdr.std_id;
|
||||
}
|
||||
frame.fd = hdr.fdf;
|
||||
frame.rtr = hdr.rtr ? CAN_REMOTEREQUEST :
|
||||
CAN_DATAFRAME;
|
||||
frame.id_type = hdr.xtd ? CAN_EXTENDED_IDENTIFIER :
|
||||
CAN_STANDARD_IDENTIFIER;
|
||||
frame.dlc = hdr.dlc;
|
||||
frame.brs = hdr.brs;
|
||||
|
||||
if (hdr.rtr != 0) {
|
||||
frame.flags |= CAN_FRAME_RTR;
|
||||
}
|
||||
|
||||
if (hdr.fdf != 0) {
|
||||
frame.flags |= CAN_FRAME_FDF;
|
||||
}
|
||||
|
||||
if (hdr.brs != 0) {
|
||||
frame.flags |= CAN_FRAME_BRS;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_CAN_RX_TIMESTAMP)
|
||||
frame.timestamp = hdr.rxts;
|
||||
#endif
|
||||
|
@ -655,39 +651,42 @@ static void can_mcan_get_message(const struct device *dev,
|
|||
filt_idx = hdr.fidx;
|
||||
|
||||
if (hdr.xtd != 0) {
|
||||
frame.id = hdr.ext_id;
|
||||
frame.flags |= CAN_FRAME_IDE;
|
||||
rtr_filter_mask = (data->ext_filt_rtr_mask & BIT(filt_idx)) != 0;
|
||||
rtr_filter = (data->ext_filt_rtr & BIT(filt_idx)) != 0;
|
||||
} else {
|
||||
frame.id = hdr.std_id;
|
||||
rtr_filter_mask = (data->std_filt_rtr_mask & BIT(filt_idx)) != 0;
|
||||
rtr_filter = (data->std_filt_rtr & BIT(filt_idx)) != 0;
|
||||
}
|
||||
|
||||
if (rtr_filter_mask && (rtr_filter != frame.rtr)) {
|
||||
/* RTR bit does not match filter RTR mask and bit, drop frame */
|
||||
if (rtr_filter_mask && (rtr_filter != ((frame.flags & CAN_FRAME_RTR) != 0))) {
|
||||
/* RTR bit does not match filter RTR mask, drop frame */
|
||||
*fifo_ack_reg = get_idx;
|
||||
continue;
|
||||
}
|
||||
|
||||
data_length = can_dlc_to_bytes(frame.dlc);
|
||||
if (data_length <= sizeof(frame.data)) {
|
||||
/* data needs to be written in 32 bit blocks!*/
|
||||
/* Data needs to be written in 32 bit blocks! */
|
||||
sys_cache_data_range((void *)fifo[get_idx].data_32,
|
||||
ROUND_UP(data_length, sizeof(uint32_t)),
|
||||
K_CACHE_INVD);
|
||||
memcpy32_volatile(frame.data_32, fifo[get_idx].data_32,
|
||||
ROUND_UP(data_length, sizeof(uint32_t)));
|
||||
|
||||
if (frame.id_type == CAN_STANDARD_IDENTIFIER) {
|
||||
LOG_DBG("Frame on filter %d, ID: 0x%x",
|
||||
filt_idx, frame.id);
|
||||
cb = data->rx_cb_std[filt_idx];
|
||||
cb_arg = data->cb_arg_std[filt_idx];
|
||||
} else {
|
||||
if ((frame.flags & CAN_FRAME_IDE) != 0) {
|
||||
LOG_DBG("Frame on filter %d, ID: 0x%x",
|
||||
filt_idx + NUM_STD_FILTER_DATA,
|
||||
frame.id);
|
||||
cb = data->rx_cb_ext[filt_idx];
|
||||
cb_arg = data->cb_arg_ext[filt_idx];
|
||||
} else {
|
||||
LOG_DBG("Frame on filter %d, ID: 0x%x",
|
||||
filt_idx, frame.id);
|
||||
cb = data->rx_cb_std[filt_idx];
|
||||
cb_arg = data->cb_arg_std[filt_idx];
|
||||
}
|
||||
|
||||
if (cb) {
|
||||
|
@ -798,15 +797,18 @@ int can_mcan_send(const struct device *dev,
|
|||
struct can_mcan_msg_sram *msg_ram = data->msg_ram;
|
||||
size_t data_length = can_dlc_to_bytes(frame->dlc);
|
||||
struct can_mcan_tx_buffer_hdr tx_hdr = {
|
||||
.rtr = frame->rtr == CAN_REMOTEREQUEST,
|
||||
.xtd = frame->id_type == CAN_EXTENDED_IDENTIFIER,
|
||||
.esi = 0,
|
||||
.rtr = (frame->flags & CAN_FRAME_RTR) != 0 ? 1U : 0U,
|
||||
.xtd = (frame->flags & CAN_FRAME_IDE) != 0 ? 1U : 0U,
|
||||
.esi = 0U,
|
||||
.dlc = frame->dlc,
|
||||
#ifdef CONFIG_CAN_FD_MODE
|
||||
.brs = frame->brs == true,
|
||||
#endif
|
||||
.fdf = frame->fd,
|
||||
.efc = 1,
|
||||
.fdf = (frame->flags & CAN_FRAME_FDF) != 0 ? 1U : 0U,
|
||||
.brs = (frame->flags & CAN_FRAME_BRS) != 0 ? 1U : 0U,
|
||||
#else /* CONFIG_CAN_FD_MODE */
|
||||
.fdf = 0U,
|
||||
.brs = 0U,
|
||||
#endif /* !CONFIG_CAN_FD_MODE */
|
||||
.efc = 1U,
|
||||
};
|
||||
uint32_t put_idx;
|
||||
int ret;
|
||||
|
@ -814,23 +816,52 @@ int can_mcan_send(const struct device *dev,
|
|||
|
||||
LOG_DBG("Sending %d bytes. Id: 0x%x, ID type: %s %s %s %s",
|
||||
data_length, frame->id,
|
||||
frame->id_type == CAN_STANDARD_IDENTIFIER ?
|
||||
"standard" : "extended",
|
||||
frame->rtr == CAN_DATAFRAME ? "" : "RTR",
|
||||
frame->fd == CAN_DATAFRAME ? "" : "FD frame",
|
||||
frame->brs == CAN_DATAFRAME ? "" : "BRS");
|
||||
(frame->flags & CAN_FRAME_IDE) != 0 ? "extended" : "standard",
|
||||
(frame->flags & CAN_FRAME_RTR) != 0 ? "RTR" : "",
|
||||
(frame->flags & CAN_FRAME_FDF) != 0 ? "FD frame" : "",
|
||||
(frame->flags & CAN_FRAME_BRS) != 0 ? "BRS" : "");
|
||||
|
||||
__ASSERT_NO_MSG(callback != NULL);
|
||||
|
||||
#ifdef CONFIG_CAN_FD_MODE
|
||||
if ((frame->flags & ~(CAN_FRAME_IDE | CAN_FRAME_RTR |
|
||||
CAN_FRAME_FDF | CAN_FRAME_BRS)) != 0) {
|
||||
LOG_ERR("unsupported CAN frame flags 0x%02x", frame->flags);
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
if ((frame->flags & CAN_FRAME_FDF) != 0 && (can->cccr & CAN_MCAN_CCCR_FDOE) == 0) {
|
||||
LOG_ERR("CAN-FD format not supported in non-FD mode");
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
if ((frame->flags & CAN_FRAME_BRS) != 0 && (can->cccr & CAN_MCAN_CCCR_BRSE) == 0) {
|
||||
LOG_ERR("CAN-FD BRS not supported in non-FD mode");
|
||||
return -ENOTSUP;
|
||||
}
|
||||
#else /* CONFIG_CAN_FD_MODE */
|
||||
if ((frame->flags & ~(CAN_FRAME_IDE | CAN_FRAME_RTR)) != 0) {
|
||||
LOG_ERR("unsupported CAN frame flags 0x%02x", frame->flags);
|
||||
return -ENOTSUP;
|
||||
}
|
||||
#endif /* !CONFIG_CAN_FD_MODE */
|
||||
|
||||
if (data_length > sizeof(frame->data)) {
|
||||
LOG_ERR("data length (%zu) > max frame data length (%zu)",
|
||||
data_length, sizeof(frame->data));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (frame->fd != 1 && frame->dlc > MCAN_MAX_DLC) {
|
||||
LOG_ERR("DLC of %d without fd flag set.", frame->dlc);
|
||||
return -EINVAL;
|
||||
if ((frame->flags & CAN_FRAME_FDF) != 0) {
|
||||
if (frame->dlc > CANFD_MAX_DLC) {
|
||||
LOG_ERR("DLC of %d for CAN-FD format frame", frame->dlc);
|
||||
return -EINVAL;
|
||||
}
|
||||
} else {
|
||||
if (frame->dlc > CAN_MAX_DLC) {
|
||||
LOG_ERR("DLC of %d for non-FD format frame", frame->dlc);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
if (!data->started) {
|
||||
|
@ -858,10 +889,10 @@ int can_mcan_send(const struct device *dev,
|
|||
mm.cnt = data->mm.cnt++;
|
||||
tx_hdr.mm = mm;
|
||||
|
||||
if (frame->id_type == CAN_STANDARD_IDENTIFIER) {
|
||||
tx_hdr.std_id = frame->id & CAN_STD_ID_MASK;
|
||||
} else {
|
||||
if ((frame->flags & CAN_FRAME_IDE) != 0) {
|
||||
tx_hdr.ext_id = frame->id;
|
||||
} else {
|
||||
tx_hdr.std_id = frame->id & CAN_STD_ID_MASK;
|
||||
}
|
||||
|
||||
memcpy32_volatile(&msg_ram->tx_buffer[put_idx].hdr, &tx_hdr, sizeof(tx_hdr));
|
||||
|
@ -892,14 +923,14 @@ static int can_mcan_get_free_std(volatile struct can_mcan_std_filter *filters)
|
|||
return -ENOSPC;
|
||||
}
|
||||
|
||||
int can_mcan_get_max_filters(const struct device *dev, enum can_ide id_type)
|
||||
int can_mcan_get_max_filters(const struct device *dev, bool ide)
|
||||
{
|
||||
ARG_UNUSED(dev);
|
||||
|
||||
if (id_type == CAN_STANDARD_IDENTIFIER) {
|
||||
return NUM_STD_FILTER_DATA;
|
||||
} else {
|
||||
if (ide) {
|
||||
return NUM_EXT_FILTER_DATA;
|
||||
} else {
|
||||
return NUM_STD_FILTER_DATA;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -916,11 +947,16 @@ int can_mcan_add_rx_filter_std(const struct device *dev,
|
|||
struct can_mcan_msg_sram *msg_ram = data->msg_ram;
|
||||
struct can_mcan_std_filter filter_element = {
|
||||
.id1 = filter->id,
|
||||
.id2 = filter->id_mask,
|
||||
.id2 = filter->mask,
|
||||
.sft = CAN_MCAN_SFT_MASKED
|
||||
};
|
||||
int filter_id;
|
||||
|
||||
if ((filter->flags & ~(CAN_FILTER_IDE | CAN_FILTER_DATA | CAN_FILTER_RTR)) != 0) {
|
||||
LOG_ERR("unsupported CAN filter flags 0x%02x", filter->flags);
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
k_mutex_lock(&data->inst_mutex, K_FOREVER);
|
||||
filter_id = can_mcan_get_free_std(msg_ram->std_filt);
|
||||
|
||||
|
@ -943,13 +979,14 @@ int can_mcan_add_rx_filter_std(const struct device *dev,
|
|||
|
||||
LOG_DBG("Attached std filter at %d", filter_id);
|
||||
|
||||
if (filter->rtr) {
|
||||
if ((filter->flags & CAN_FILTER_RTR) != 0) {
|
||||
data->std_filt_rtr |= (1U << filter_id);
|
||||
} else {
|
||||
data->std_filt_rtr &= ~(1U << filter_id);
|
||||
}
|
||||
|
||||
if (filter->rtr_mask) {
|
||||
if ((filter->flags & (CAN_FILTER_DATA | CAN_FILTER_RTR)) !=
|
||||
(CAN_FILTER_DATA | CAN_FILTER_RTR)) {
|
||||
data->std_filt_rtr_mask |= (1U << filter_id);
|
||||
} else {
|
||||
data->std_filt_rtr_mask &= ~(1U << filter_id);
|
||||
|
@ -979,7 +1016,7 @@ static int can_mcan_add_rx_filter_ext(const struct device *dev,
|
|||
struct can_mcan_data *data = dev->data;
|
||||
struct can_mcan_msg_sram *msg_ram = data->msg_ram;
|
||||
struct can_mcan_ext_filter filter_element = {
|
||||
.id2 = filter->id_mask,
|
||||
.id2 = filter->mask,
|
||||
.id1 = filter->id,
|
||||
.eft = CAN_MCAN_EFT_MASKED
|
||||
};
|
||||
|
@ -1007,13 +1044,14 @@ static int can_mcan_add_rx_filter_ext(const struct device *dev,
|
|||
|
||||
LOG_DBG("Attached ext filter at %d", filter_id);
|
||||
|
||||
if (filter->rtr) {
|
||||
if ((filter->flags & CAN_FILTER_RTR) != 0) {
|
||||
data->ext_filt_rtr |= (1U << filter_id);
|
||||
} else {
|
||||
data->ext_filt_rtr &= ~(1U << filter_id);
|
||||
}
|
||||
|
||||
if (filter->rtr_mask) {
|
||||
if ((filter->flags & (CAN_FILTER_DATA | CAN_FILTER_RTR)) !=
|
||||
(CAN_FILTER_DATA | CAN_FILTER_RTR)) {
|
||||
data->ext_filt_rtr_mask |= (1U << filter_id);
|
||||
} else {
|
||||
data->ext_filt_rtr_mask &= ~(1U << filter_id);
|
||||
|
@ -1035,13 +1073,13 @@ int can_mcan_add_rx_filter(const struct device *dev,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (filter->id_type == CAN_STANDARD_IDENTIFIER) {
|
||||
filter_id = can_mcan_add_rx_filter_std(dev, callback, user_data, filter);
|
||||
} else {
|
||||
if ((filter->flags & CAN_FILTER_IDE) != 0) {
|
||||
filter_id = can_mcan_add_rx_filter_ext(dev, callback, user_data, filter);
|
||||
if (filter_id >= 0) {
|
||||
filter_id += NUM_STD_FILTER_DATA;
|
||||
}
|
||||
} else {
|
||||
filter_id = can_mcan_add_rx_filter_std(dev, callback, user_data, filter);
|
||||
}
|
||||
|
||||
return filter_id;
|
||||
|
|
|
@ -283,7 +283,7 @@ int can_mcan_send(const struct device *dev, const struct can_frame *frame,
|
|||
k_timeout_t timeout, can_tx_callback_t callback,
|
||||
void *user_data);
|
||||
|
||||
int can_mcan_get_max_filters(const struct device *dev, enum can_ide id_type);
|
||||
int can_mcan_get_max_filters(const struct device *dev, bool ide);
|
||||
|
||||
int can_mcan_add_rx_filter(const struct device *dev,
|
||||
can_rx_callback_t callback, void *user_data,
|
||||
|
|
|
@ -222,20 +222,20 @@ static void mcp2515_convert_canframe_to_mcp2515frame(const struct can_frame
|
|||
uint8_t dlc;
|
||||
uint8_t data_idx = 0U;
|
||||
|
||||
if (source->id_type == CAN_STANDARD_IDENTIFIER) {
|
||||
target[MCP2515_FRAME_OFFSET_SIDH] = source->id >> 3;
|
||||
target[MCP2515_FRAME_OFFSET_SIDL] =
|
||||
(source->id & 0x07) << 5;
|
||||
} else {
|
||||
if ((source->flags & CAN_FRAME_IDE) != 0) {
|
||||
target[MCP2515_FRAME_OFFSET_SIDH] = source->id >> 21;
|
||||
target[MCP2515_FRAME_OFFSET_SIDL] =
|
||||
(((source->id >> 18) & 0x07) << 5) | (BIT(3)) |
|
||||
((source->id >> 16) & 0x03);
|
||||
target[MCP2515_FRAME_OFFSET_EID8] = source->id >> 8;
|
||||
target[MCP2515_FRAME_OFFSET_EID0] = source->id;
|
||||
} else {
|
||||
target[MCP2515_FRAME_OFFSET_SIDH] = source->id >> 3;
|
||||
target[MCP2515_FRAME_OFFSET_SIDL] =
|
||||
(source->id & 0x07) << 5;
|
||||
}
|
||||
|
||||
rtr = (source->rtr == CAN_REMOTEREQUEST) ? BIT(6) : 0;
|
||||
rtr = (source->flags & CAN_FRAME_RTR) != 0 ? BIT(6) : 0;
|
||||
dlc = (source->dlc) & 0x0F;
|
||||
|
||||
target[MCP2515_FRAME_OFFSET_DLC] = rtr | dlc;
|
||||
|
@ -251,8 +251,10 @@ static void mcp2515_convert_mcp2515frame_to_canframe(const uint8_t *source,
|
|||
{
|
||||
uint8_t data_idx = 0U;
|
||||
|
||||
memset(target, 0, sizeof(*target));
|
||||
|
||||
if (source[MCP2515_FRAME_OFFSET_SIDL] & BIT(3)) {
|
||||
target->id_type = CAN_EXTENDED_IDENTIFIER;
|
||||
target->flags |= CAN_FRAME_IDE;
|
||||
target->id =
|
||||
(source[MCP2515_FRAME_OFFSET_SIDH] << 21) |
|
||||
((source[MCP2515_FRAME_OFFSET_SIDL] >> 5) << 18) |
|
||||
|
@ -260,14 +262,15 @@ static void mcp2515_convert_mcp2515frame_to_canframe(const uint8_t *source,
|
|||
(source[MCP2515_FRAME_OFFSET_EID8] << 8) |
|
||||
source[MCP2515_FRAME_OFFSET_EID0];
|
||||
} else {
|
||||
target->id_type = CAN_STANDARD_IDENTIFIER;
|
||||
target->id = (source[MCP2515_FRAME_OFFSET_SIDH] << 3) |
|
||||
(source[MCP2515_FRAME_OFFSET_SIDL] >> 5);
|
||||
}
|
||||
|
||||
target->dlc = source[MCP2515_FRAME_OFFSET_DLC] & 0x0F;
|
||||
target->rtr = source[MCP2515_FRAME_OFFSET_DLC] & BIT(6) ?
|
||||
CAN_REMOTEREQUEST : CAN_DATAFRAME;
|
||||
|
||||
if ((source[MCP2515_FRAME_OFFSET_DLC] & BIT(6)) != 0) {
|
||||
target->flags |= CAN_FRAME_RTR;
|
||||
}
|
||||
|
||||
for (; data_idx < CAN_MAX_DLC; data_idx++) {
|
||||
target->data[data_idx] = source[MCP2515_FRAME_OFFSET_D0 +
|
||||
|
@ -323,9 +326,9 @@ static int mcp2515_get_core_clock(const struct device *dev, uint32_t *rate)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int mcp2515_get_max_filters(const struct device *dev, enum can_ide id_type)
|
||||
static int mcp2515_get_max_filters(const struct device *dev, bool ide)
|
||||
{
|
||||
ARG_UNUSED(id_type);
|
||||
ARG_UNUSED(ide);
|
||||
|
||||
return CONFIG_CAN_MAX_FILTER;
|
||||
}
|
||||
|
@ -577,6 +580,11 @@ static int mcp2515_send(const struct device *dev,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ((frame->flags & ~(CAN_FRAME_IDE | CAN_FRAME_RTR)) != 0) {
|
||||
LOG_ERR("unsupported CAN frame flags 0x%02x", frame->flags);
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
if (!dev_data->started) {
|
||||
return -ENETDOWN;
|
||||
}
|
||||
|
@ -632,6 +640,11 @@ static int mcp2515_add_rx_filter(const struct device *dev,
|
|||
|
||||
__ASSERT(rx_cb != NULL, "response_ptr can not be null");
|
||||
|
||||
if ((filter->flags & ~(CAN_FILTER_IDE | CAN_FILTER_DATA | CAN_FILTER_RTR)) != 0) {
|
||||
LOG_ERR("unsupported CAN filter flags 0x%02x", filter->flags);
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
k_mutex_lock(&dev_data->mutex, K_FOREVER);
|
||||
|
||||
/* find free filter */
|
||||
|
|
|
@ -135,9 +135,9 @@ static int mcux_flexcan_get_core_clock(const struct device *dev, uint32_t *rate)
|
|||
return clock_control_get_rate(config->clock_dev, config->clock_subsys, rate);
|
||||
}
|
||||
|
||||
static int mcux_flexcan_get_max_filters(const struct device *dev, enum can_ide id_type)
|
||||
static int mcux_flexcan_get_max_filters(const struct device *dev, bool ide)
|
||||
{
|
||||
ARG_UNUSED(id_type);
|
||||
ARG_UNUSED(ide);
|
||||
|
||||
return CONFIG_CAN_MAX_FILTER;
|
||||
}
|
||||
|
@ -313,18 +313,20 @@ static int mcux_flexcan_set_mode(const struct device *dev, can_mode_t mode)
|
|||
static void mcux_flexcan_from_can_frame(const struct can_frame *src,
|
||||
flexcan_frame_t *dest)
|
||||
{
|
||||
if (src->id_type == CAN_STANDARD_IDENTIFIER) {
|
||||
dest->format = kFLEXCAN_FrameFormatStandard;
|
||||
dest->id = FLEXCAN_ID_STD(src->id);
|
||||
} else {
|
||||
memset(dest, 0, sizeof(*dest));
|
||||
|
||||
if ((src->flags & CAN_FRAME_IDE) != 0) {
|
||||
dest->format = kFLEXCAN_FrameFormatExtend;
|
||||
dest->id = FLEXCAN_ID_EXT(src->id);
|
||||
} else {
|
||||
dest->format = kFLEXCAN_FrameFormatStandard;
|
||||
dest->id = FLEXCAN_ID_STD(src->id);
|
||||
}
|
||||
|
||||
if (src->rtr == CAN_DATAFRAME) {
|
||||
dest->type = kFLEXCAN_FrameTypeData;
|
||||
} else {
|
||||
if ((src->flags & CAN_FRAME_RTR) != 0) {
|
||||
dest->type = kFLEXCAN_FrameTypeRemote;
|
||||
} else {
|
||||
dest->type = kFLEXCAN_FrameTypeData;
|
||||
}
|
||||
|
||||
dest->length = src->dlc;
|
||||
|
@ -335,18 +337,17 @@ static void mcux_flexcan_from_can_frame(const struct can_frame *src,
|
|||
static void mcux_flexcan_to_can_frame(const flexcan_frame_t *src,
|
||||
struct can_frame *dest)
|
||||
{
|
||||
memset(dest, 0, sizeof(*dest));
|
||||
|
||||
if (src->format == kFLEXCAN_FrameFormatStandard) {
|
||||
dest->id_type = CAN_STANDARD_IDENTIFIER;
|
||||
dest->id = FLEXCAN_ID_TO_CAN_ID_STD(src->id);
|
||||
} else {
|
||||
dest->id_type = CAN_EXTENDED_IDENTIFIER;
|
||||
dest->flags |= CAN_FRAME_IDE;
|
||||
dest->id = FLEXCAN_ID_TO_CAN_ID_EXT(src->id);
|
||||
}
|
||||
|
||||
if (src->type == kFLEXCAN_FrameTypeData) {
|
||||
dest->rtr = CAN_DATAFRAME;
|
||||
} else {
|
||||
dest->rtr = CAN_REMOTEREQUEST;
|
||||
if (src->type == kFLEXCAN_FrameTypeRemote) {
|
||||
dest->flags |= CAN_FRAME_RTR;
|
||||
}
|
||||
|
||||
dest->dlc = src->length;
|
||||
|
@ -361,20 +362,24 @@ static void mcux_flexcan_can_filter_to_mbconfig(const struct can_filter *src,
|
|||
flexcan_rx_mb_config_t *dest,
|
||||
uint32_t *mask)
|
||||
{
|
||||
if (src->id_type == CAN_STANDARD_IDENTIFIER) {
|
||||
dest->format = kFLEXCAN_FrameFormatStandard;
|
||||
dest->id = FLEXCAN_ID_STD(src->id);
|
||||
*mask = FLEXCAN_RX_MB_STD_MASK(src->id_mask, src->rtr_mask, 1);
|
||||
} else {
|
||||
static const uint32_t ide_mask = 1U;
|
||||
uint32_t rtr_mask = (src->flags & (CAN_FILTER_DATA | CAN_FILTER_RTR)) !=
|
||||
(CAN_FILTER_DATA | CAN_FILTER_RTR) ? 1U : 0U;
|
||||
|
||||
if ((src->flags & CAN_FILTER_IDE) != 0) {
|
||||
dest->format = kFLEXCAN_FrameFormatExtend;
|
||||
dest->id = FLEXCAN_ID_EXT(src->id);
|
||||
*mask = FLEXCAN_RX_MB_EXT_MASK(src->id_mask, src->rtr_mask, 1);
|
||||
*mask = FLEXCAN_RX_MB_EXT_MASK(src->mask, rtr_mask, ide_mask);
|
||||
} else {
|
||||
dest->format = kFLEXCAN_FrameFormatStandard;
|
||||
dest->id = FLEXCAN_ID_STD(src->id);
|
||||
*mask = FLEXCAN_RX_MB_STD_MASK(src->mask, rtr_mask, ide_mask);
|
||||
}
|
||||
|
||||
if ((src->rtr & src->rtr_mask) == CAN_DATAFRAME) {
|
||||
dest->type = kFLEXCAN_FrameTypeData;
|
||||
} else {
|
||||
if ((src->flags & CAN_FILTER_RTR) != 0) {
|
||||
dest->type = kFLEXCAN_FrameTypeRemote;
|
||||
} else {
|
||||
dest->type = kFLEXCAN_FrameTypeData;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -431,6 +436,11 @@ static int mcux_flexcan_send(const struct device *dev,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ((frame->flags & ~(CAN_FRAME_IDE | CAN_FRAME_RTR)) != 0) {
|
||||
LOG_ERR("unsupported CAN frame flags 0x%02x", frame->flags);
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
if (!data->started) {
|
||||
return -ENETDOWN;
|
||||
}
|
||||
|
@ -481,6 +491,11 @@ static int mcux_flexcan_add_rx_filter(const struct device *dev,
|
|||
|
||||
__ASSERT_NO_MSG(callback);
|
||||
|
||||
if ((filter->flags & ~(CAN_FILTER_IDE | CAN_FILTER_DATA | CAN_FILTER_RTR)) != 0) {
|
||||
LOG_ERR("unsupported CAN filter flags 0x%02x", filter->flags);
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
k_mutex_lock(&data->rx_mutex, K_FOREVER);
|
||||
|
||||
/* Find and allocate RX message buffer */
|
||||
|
|
|
@ -109,9 +109,8 @@ static void rx_thread(void *arg1, void *arg2, void *arg3)
|
|||
|
||||
LOG_DBG("Received %d bytes. Id: 0x%x, ID type: %s %s",
|
||||
frame.dlc, frame.id,
|
||||
frame.id_type == CAN_STANDARD_IDENTIFIER ?
|
||||
"standard" : "extended",
|
||||
frame.rtr == CAN_DATAFRAME ? "" : ", RTR frame");
|
||||
(frame.flags & CAN_FRAME_IDE) != 0 ? "extended" : "standard",
|
||||
(frame.flags & CAN_FRAME_RTR) != 0 ? ", RTR frame" : "");
|
||||
|
||||
dispatch_frame(dev, &frame);
|
||||
}
|
||||
|
@ -132,18 +131,32 @@ static int can_npl_send(const struct device *dev, const struct can_frame *frame,
|
|||
|
||||
LOG_DBG("Sending %d bytes on %s. Id: 0x%x, ID type: %s %s",
|
||||
frame->dlc, dev->name, frame->id,
|
||||
frame->id_type == CAN_STANDARD_IDENTIFIER ?
|
||||
"standard" : "extended",
|
||||
frame->rtr == CAN_DATAFRAME ? "" : ", RTR frame");
|
||||
(frame->flags & CAN_FRAME_IDE) != 0 ? "extended" : "standard",
|
||||
(frame->flags & CAN_FRAME_RTR) != 0 ? ", RTR frame" : "");
|
||||
|
||||
__ASSERT_NO_MSG(callback != NULL);
|
||||
|
||||
#ifdef CONFIG_CAN_FD_MODE
|
||||
if (data->mode_fd && frame->fd == 1) {
|
||||
if ((frame->flags & ~(CAN_FRAME_IDE | CAN_FRAME_RTR |
|
||||
CAN_FRAME_FDF | CAN_FRAME_BRS)) != 0) {
|
||||
LOG_ERR("unsupported CAN frame flags 0x%02x", frame->flags);
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
if ((frame->flags & CAN_FRAME_FDF) != 0) {
|
||||
if (!data->mode_fd) {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
max_dlc = CANFD_MAX_DLC;
|
||||
mtu = CANFD_MTU;
|
||||
}
|
||||
#endif /* CONFIG_CAN_FD_MODE */
|
||||
#else /* CONFIG_CAN_FD_MODE */
|
||||
if ((frame->flags & ~(CAN_FRAME_IDE | CAN_FRAME_RTR)) != 0) {
|
||||
LOG_ERR("unsupported CAN frame flags 0x%02x", frame->flags);
|
||||
return -ENOTSUP;
|
||||
}
|
||||
#endif /* !CONFIG_CAN_FD_MODE */
|
||||
|
||||
if (frame->dlc > max_dlc) {
|
||||
LOG_ERR("DLC of %d exceeds maximum (%d)", frame->dlc, max_dlc);
|
||||
|
@ -184,13 +197,12 @@ static int can_npl_add_rx_filter(const struct device *dev, can_rx_callback_t cb,
|
|||
int filter_id = -ENOSPC;
|
||||
|
||||
LOG_DBG("Setting filter ID: 0x%x, mask: 0x%x", filter->id,
|
||||
filter->id_mask);
|
||||
LOG_DBG("Filter type: %s ID %s mask",
|
||||
filter->id_type == CAN_STANDARD_IDENTIFIER ?
|
||||
"standard" : "extended",
|
||||
((filter->id_type && (filter->id_mask == CAN_STD_ID_MASK)) ||
|
||||
(!filter->id_type && (filter->id_mask == CAN_EXT_ID_MASK))) ?
|
||||
"with" : "without");
|
||||
filter->mask);
|
||||
|
||||
if ((filter->flags & ~(CAN_FILTER_IDE | CAN_FILTER_DATA | CAN_FILTER_RTR)) != 0) {
|
||||
LOG_ERR("unsupported CAN filter flags 0x%02x", filter->flags);
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
k_mutex_lock(&data->filter_mutex, K_FOREVER);
|
||||
|
||||
|
@ -384,9 +396,9 @@ static int can_npl_get_core_clock(const struct device *dev, uint32_t *rate)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int can_npl_get_max_filters(const struct device *dev, enum can_ide id_type)
|
||||
static int can_npl_get_max_filters(const struct device *dev, bool ide)
|
||||
{
|
||||
ARG_UNUSED(id_type);
|
||||
ARG_UNUSED(ide);
|
||||
|
||||
return CONFIG_CAN_MAX_FILTER;
|
||||
}
|
||||
|
|
|
@ -389,23 +389,20 @@ static void can_rcar_rx_isr(const struct device *dev)
|
|||
{
|
||||
const struct can_rcar_cfg *config = dev->config;
|
||||
struct can_rcar_data *data = dev->data;
|
||||
struct can_frame frame;
|
||||
struct can_frame frame = {0};
|
||||
uint32_t val;
|
||||
int i;
|
||||
|
||||
val = sys_read32(config->reg_addr + RCAR_CAN_MB_60);
|
||||
if (val & RCAR_CAN_MB_IDE) {
|
||||
frame.id_type = CAN_EXTENDED_IDENTIFIER;
|
||||
frame.flags |= CAN_FRAME_IDE;
|
||||
frame.id = val & RCAR_CAN_MB_EID_MASK;
|
||||
} else {
|
||||
frame.id_type = CAN_STANDARD_IDENTIFIER;
|
||||
frame.id = (val & RCAR_CAN_MB_SID_MASK) >> RCAR_CAN_MB_SID_SHIFT;
|
||||
}
|
||||
|
||||
if (val & RCAR_CAN_MB_RTR) {
|
||||
frame.rtr = CAN_REMOTEREQUEST;
|
||||
} else {
|
||||
frame.rtr = CAN_DATAFRAME;
|
||||
frame.flags |= CAN_FRAME_RTR;
|
||||
}
|
||||
|
||||
frame.dlc = sys_read16(config->reg_addr +
|
||||
|
@ -856,9 +853,9 @@ static int can_rcar_send(const struct device *dev, const struct can_frame *frame
|
|||
"Remote Frame: %s"
|
||||
, frame->dlc, dev->name
|
||||
, frame->id
|
||||
, frame->id_type == CAN_STANDARD_IDENTIFIER ?
|
||||
"standard" : "extended"
|
||||
, frame->rtr == CAN_DATAFRAME ? "no" : "yes");
|
||||
, (frame->flags & CAN_FRAME_IDE) != 0 ?
|
||||
"extended" : "standard"
|
||||
, (frame->flags & CAN_FRAME_RTR) != 0 ? "yes" : "no");
|
||||
|
||||
__ASSERT_NO_MSG(callback != NULL);
|
||||
__ASSERT(frame->dlc == 0U || frame->data != NULL, "Dataptr is null");
|
||||
|
@ -869,6 +866,11 @@ static int can_rcar_send(const struct device *dev, const struct can_frame *frame
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ((frame->flags & ~(CAN_FRAME_IDE | CAN_FRAME_RTR)) != 0) {
|
||||
LOG_ERR("unsupported CAN frame flags 0x%02x", frame->flags);
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
if (!data->started) {
|
||||
return -ENETDOWN;
|
||||
}
|
||||
|
@ -888,13 +890,13 @@ static int can_rcar_send(const struct device *dev, const struct can_frame *frame
|
|||
data->tx_head = 0;
|
||||
}
|
||||
|
||||
if (frame->id_type == CAN_STANDARD_IDENTIFIER) {
|
||||
identifier = frame->id << RCAR_CAN_MB_SID_SHIFT;
|
||||
} else {
|
||||
if ((frame->flags & CAN_FRAME_IDE) != 0) {
|
||||
identifier = frame->id | RCAR_CAN_MB_IDE;
|
||||
} else {
|
||||
identifier = frame->id << RCAR_CAN_MB_SID_SHIFT;
|
||||
}
|
||||
|
||||
if (frame->rtr == CAN_REMOTEREQUEST) {
|
||||
if ((frame->flags & CAN_FRAME_RTR) != 0) {
|
||||
identifier |= RCAR_CAN_MB_RTR;
|
||||
}
|
||||
|
||||
|
@ -947,7 +949,8 @@ static int can_rcar_add_rx_filter(const struct device *dev, can_rx_callback_t cb
|
|||
struct can_rcar_data *data = dev->data;
|
||||
int filter_id;
|
||||
|
||||
if (filter->rtr == CAN_REMOTEREQUEST) {
|
||||
if ((filter->flags & ~(CAN_FILTER_IDE | CAN_FILTER_DATA)) != 0) {
|
||||
LOG_ERR("unsupported CAN filter flags 0x%02x", filter->flags);
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
|
@ -1121,9 +1124,9 @@ static int can_rcar_get_core_clock(const struct device *dev, uint32_t *rate)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int can_rcar_get_max_filters(const struct device *dev, enum can_ide id_type)
|
||||
static int can_rcar_get_max_filters(const struct device *dev, bool ide)
|
||||
{
|
||||
ARG_UNUSED(id_type);
|
||||
ARG_UNUSED(ide);
|
||||
|
||||
return CONFIG_CAN_RCAR_MAX_FILTER;
|
||||
}
|
||||
|
|
|
@ -72,29 +72,29 @@ static void can_shell_print_frame(const struct shell *sh, const struct can_frame
|
|||
|
||||
#ifdef CONFIG_CAN_FD_MODE
|
||||
/* Flags */
|
||||
shell_fprintf(sh, SHELL_NORMAL, "%c ", frame->brs == 0 ? '-' : 'B');
|
||||
shell_fprintf(sh, SHELL_NORMAL, "%c ", (frame->flags & CAN_FRAME_BRS) == 0 ? '-' : 'B');
|
||||
#endif /* CONFIG_CAN_FD_MODE */
|
||||
|
||||
/* CAN ID */
|
||||
shell_fprintf(sh, SHELL_NORMAL, "%*s%0*x ",
|
||||
frame->id_type == CAN_STANDARD_IDENTIFIER ? 5 : 0, "",
|
||||
frame->id_type == CAN_STANDARD_IDENTIFIER ? 3 : 8,
|
||||
frame->id_type == CAN_STANDARD_IDENTIFIER ?
|
||||
frame->id & CAN_STD_ID_MASK : frame->id & CAN_EXT_ID_MASK);
|
||||
(frame->flags & CAN_FRAME_IDE) != 0 ? 0 : 5, "",
|
||||
(frame->flags & CAN_FRAME_IDE) != 0 ? 8 : 3,
|
||||
(frame->flags & CAN_FRAME_IDE) != 0 ?
|
||||
frame->id & CAN_EXT_ID_MASK : frame->id & CAN_STD_ID_MASK);
|
||||
|
||||
/* DLC as number of bytes */
|
||||
shell_fprintf(sh, SHELL_NORMAL, "%s[%0*d] ",
|
||||
frame->fd == 0 ? " " : "",
|
||||
frame->fd == 0 ? 1 : 2,
|
||||
nbytes);
|
||||
(frame->flags & CAN_FRAME_FDF) != 0 ? "" : " ",
|
||||
(frame->flags & CAN_FRAME_FDF) != 0 ? 2 : 1,
|
||||
nbytes);
|
||||
|
||||
/* Data payload */
|
||||
if (frame->rtr == CAN_DATAFRAME) {
|
||||
if ((frame->flags & CAN_FRAME_RTR) != 0) {
|
||||
shell_fprintf(sh, SHELL_NORMAL, "remote transmission request");
|
||||
} else {
|
||||
for (i = 0; i < nbytes; i++) {
|
||||
shell_fprintf(sh, SHELL_NORMAL, "%02x ", frame->data[i]);
|
||||
}
|
||||
} else {
|
||||
shell_fprintf(sh, SHELL_NORMAL, "remote transmission request");
|
||||
}
|
||||
|
||||
shell_fprintf(sh, SHELL_NORMAL, "\n");
|
||||
|
@ -297,13 +297,13 @@ static int cmd_can_show(const struct shell *sh, size_t argc, char **argv)
|
|||
return err;
|
||||
}
|
||||
|
||||
max_std_filters = can_get_max_filters(dev, CAN_STANDARD_IDENTIFIER);
|
||||
max_std_filters = can_get_max_filters(dev, false);
|
||||
if (max_std_filters < 0 && max_std_filters != -ENOSYS) {
|
||||
shell_error(sh, "failed to get maximum standard (11-bit) filters (err %d)", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
max_ext_filters = can_get_max_filters(dev, CAN_EXTENDED_IDENTIFIER);
|
||||
max_ext_filters = can_get_max_filters(dev, true);
|
||||
if (max_ext_filters < 0 && max_ext_filters != -ENOSYS) {
|
||||
shell_error(sh, "failed to get maximum extended (29-bit) filters (err %d)", err);
|
||||
return err;
|
||||
|
@ -524,11 +524,8 @@ static int cmd_can_send(const struct shell *sh, size_t argc, char **argv)
|
|||
|
||||
/* Defaults */
|
||||
max_id = CAN_MAX_STD_ID;
|
||||
frame.id_type = CAN_STANDARD_IDENTIFIER;
|
||||
frame.rtr = CAN_DATAFRAME;
|
||||
frame.flags = 0;
|
||||
frame.dlc = 0;
|
||||
frame.fd = 0;
|
||||
frame.brs = 0;
|
||||
|
||||
/* Parse options */
|
||||
while (argidx < argc && strncmp(argv[argidx], "-", 1) == 0) {
|
||||
|
@ -536,17 +533,17 @@ static int cmd_can_send(const struct shell *sh, size_t argc, char **argv)
|
|||
argidx++;
|
||||
break;
|
||||
} else if (strcmp(argv[argidx], "-e") == 0) {
|
||||
frame.id_type = CAN_EXTENDED_IDENTIFIER;
|
||||
frame.flags |= CAN_FRAME_IDE;
|
||||
max_id = CAN_MAX_EXT_ID;
|
||||
argidx++;
|
||||
} else if (strcmp(argv[argidx], "-r") == 0) {
|
||||
frame.rtr = CAN_REMOTEREQUEST;
|
||||
frame.flags |= CAN_FRAME_RTR;
|
||||
argidx++;
|
||||
} else if (strcmp(argv[argidx], "-f") == 0) {
|
||||
frame.fd = 1;
|
||||
frame.flags |= CAN_FRAME_FDF;
|
||||
argidx++;
|
||||
} else if (strcmp(argv[argidx], "-b") == 0) {
|
||||
frame.brs = 1;
|
||||
frame.flags |= CAN_FRAME_BRS;
|
||||
argidx++;
|
||||
} else {
|
||||
shell_error(sh, "unsupported option %s", argv[argidx]);
|
||||
|
@ -570,7 +567,7 @@ static int cmd_can_send(const struct shell *sh, size_t argc, char **argv)
|
|||
|
||||
if (val > max_id) {
|
||||
shell_error(sh, "CAN ID 0x%0*x out of range",
|
||||
frame.id_type == CAN_STANDARD_IDENTIFIER ? 3 : 8,
|
||||
(frame.flags & CAN_FRAME_IDE) != 0 ? 8 : 3,
|
||||
val);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -610,10 +607,13 @@ static int cmd_can_send(const struct shell *sh, size_t argc, char **argv)
|
|||
|
||||
shell_print(sh, "enqueuing CAN frame #%u with %s (%d-bit) CAN ID 0x%0*x, "
|
||||
"RTR %d, CAN-FD %d, BRS %d, DLC %d", frame_no,
|
||||
frame.id_type == CAN_STANDARD_IDENTIFIER ? "standard" : "extended",
|
||||
frame.id_type == CAN_STANDARD_IDENTIFIER ? 11 : 29,
|
||||
frame.id_type == CAN_STANDARD_IDENTIFIER ? 3 : 8, frame.id,
|
||||
frame.rtr, frame.fd, frame.brs, can_dlc_to_bytes(frame.dlc));
|
||||
(frame.flags & CAN_FRAME_IDE) != 0 ? "extended" : "standard",
|
||||
(frame.flags & CAN_FRAME_IDE) != 0 ? 29 : 11,
|
||||
(frame.flags & CAN_FRAME_IDE) != 0 ? 8 : 3, frame.id,
|
||||
(frame.flags & CAN_FRAME_RTR) != 0 ? 1 : 0,
|
||||
(frame.flags & CAN_FRAME_FDF) != 0 ? 1 : 0,
|
||||
(frame.flags & CAN_FRAME_BRS) != 0 ? 1 : 0,
|
||||
can_dlc_to_bytes(frame.dlc));
|
||||
|
||||
err = can_send(dev, &frame, K_NO_WAIT, can_shell_tx_callback, UINT_TO_POINTER(frame_no));
|
||||
if (err != 0) {
|
||||
|
@ -641,9 +641,7 @@ static int cmd_can_filter_add(const struct shell *sh, size_t argc, char **argv)
|
|||
|
||||
/* Defaults */
|
||||
max_id = CAN_MAX_STD_ID;
|
||||
filter.id_type = CAN_STANDARD_IDENTIFIER;
|
||||
filter.rtr = CAN_DATAFRAME;
|
||||
filter.rtr_mask = 0;
|
||||
filter.flags = CAN_FILTER_DATA;
|
||||
|
||||
/* Parse options */
|
||||
while (argidx < argc && strncmp(argv[argidx], "-", 1) == 0) {
|
||||
|
@ -651,14 +649,15 @@ static int cmd_can_filter_add(const struct shell *sh, size_t argc, char **argv)
|
|||
argidx++;
|
||||
break;
|
||||
} else if (strcmp(argv[argidx], "-e") == 0) {
|
||||
filter.id_type = CAN_EXTENDED_IDENTIFIER;
|
||||
filter.flags |= CAN_FILTER_IDE;
|
||||
max_id = CAN_MAX_EXT_ID;
|
||||
argidx++;
|
||||
} else if (strcmp(argv[argidx], "-r") == 0) {
|
||||
filter.rtr = CAN_REMOTEREQUEST;
|
||||
filter.flags |= CAN_FILTER_RTR;
|
||||
argidx++;
|
||||
} else if (strcmp(argv[argidx], "-R") == 0) {
|
||||
filter.rtr_mask = 1;
|
||||
filter.flags &= ~(CAN_FILTER_DATA);
|
||||
filter.flags |= CAN_FILTER_RTR;
|
||||
argidx++;
|
||||
} else {
|
||||
shell_error(sh, "unsupported argument %s", argv[argidx]);
|
||||
|
@ -682,7 +681,7 @@ static int cmd_can_filter_add(const struct shell *sh, size_t argc, char **argv)
|
|||
|
||||
if (val > max_id) {
|
||||
shell_error(sh, "CAN ID 0x%0*x out of range",
|
||||
filter.id_type == CAN_STANDARD_IDENTIFIER ? 3 : 8,
|
||||
(filter.flags & CAN_FILTER_IDE) != 0 ? 8 : 3,
|
||||
val);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -699,7 +698,7 @@ static int cmd_can_filter_add(const struct shell *sh, size_t argc, char **argv)
|
|||
|
||||
if (val > max_id) {
|
||||
shell_error(sh, "CAN ID mask 0x%0*x out of range",
|
||||
filter.id_type == CAN_STANDARD_IDENTIFIER ? 3 : 8,
|
||||
(filter.flags & CAN_FILTER_IDE) != 0 ? 8 : 3,
|
||||
val);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -708,7 +707,7 @@ static int cmd_can_filter_add(const struct shell *sh, size_t argc, char **argv)
|
|||
val = max_id;
|
||||
}
|
||||
|
||||
filter.id_mask = val;
|
||||
filter.mask = val;
|
||||
|
||||
err = can_shell_rx_msgq_poll_submit(sh);
|
||||
if (err != 0) {
|
||||
|
@ -716,12 +715,13 @@ static int cmd_can_filter_add(const struct shell *sh, size_t argc, char **argv)
|
|||
}
|
||||
|
||||
shell_print(sh, "adding filter with %s (%d-bit) CAN ID 0x%0*x, "
|
||||
"CAN ID mask 0x%0*x, RTR %d, RTR mask %d",
|
||||
filter.id_type == CAN_STANDARD_IDENTIFIER ? "standard" : "extended",
|
||||
filter.id_type == CAN_STANDARD_IDENTIFIER ? 11 : 29,
|
||||
filter.id_type == CAN_STANDARD_IDENTIFIER ? 3 : 8, filter.id,
|
||||
filter.id_type == CAN_STANDARD_IDENTIFIER ? 3 : 8, filter.id_mask,
|
||||
filter.rtr, filter.rtr_mask);
|
||||
"CAN ID mask 0x%0*x, data frames %d, RTR frames %d",
|
||||
(filter.flags & CAN_FILTER_IDE) != 0 ? "extended" : "standard",
|
||||
(filter.flags & CAN_FILTER_IDE) != 0 ? 29 : 11,
|
||||
(filter.flags & CAN_FILTER_IDE) != 0 ? 8 : 3, filter.id,
|
||||
(filter.flags & CAN_FILTER_IDE) != 0 ? 8 : 3, filter.mask,
|
||||
(filter.flags & CAN_FILTER_DATA) != 0 ? 1 : 0,
|
||||
(filter.flags & CAN_FILTER_RTR) != 0 ? 1 : 0);
|
||||
|
||||
err = can_add_rx_filter_msgq(dev, &can_shell_rx_msgq, &filter);
|
||||
if (err < 0) {
|
||||
|
@ -841,8 +841,8 @@ SHELL_STATIC_SUBCMD_SET_CREATE(sub_can_filter_cmds,
|
|||
"Add rx filter\n"
|
||||
"Usage: can filter add <device> [-e] [-r] [-R] <CAN ID> [CAN ID mask]\n"
|
||||
"-e use extended (29-bit) CAN ID/CAN ID mask\n"
|
||||
"-r set Remote Transmission Request (RTR) bit\n"
|
||||
"-R set Remote Transmission Request (RTR) mask",
|
||||
"-r also match Remote Transmission Request (RTR) frames\n"
|
||||
"-R only match Remote Transmission Request (RTR) frames",
|
||||
cmd_can_filter_add, 3, 4),
|
||||
SHELL_CMD_ARG(remove, &dsub_can_device_name,
|
||||
"Remove rx filter\n"
|
||||
|
|
|
@ -283,9 +283,7 @@ static void can_sja1000_read_frame(const struct device *dev, struct can_frame *f
|
|||
info = can_sja1000_read_reg(dev, CAN_SJA1000_FRAME_INFO);
|
||||
|
||||
if ((info & CAN_SJA1000_FRAME_INFO_RTR) != 0) {
|
||||
frame->rtr = CAN_REMOTEREQUEST;
|
||||
} else {
|
||||
frame->rtr = CAN_DATAFRAME;
|
||||
frame->flags |= CAN_FRAME_RTR;
|
||||
}
|
||||
|
||||
frame->dlc = CAN_SJA1000_FRAME_INFO_DLC_GET(info);
|
||||
|
@ -295,7 +293,7 @@ static void can_sja1000_read_frame(const struct device *dev, struct can_frame *f
|
|||
}
|
||||
|
||||
if ((info & CAN_SJA1000_FRAME_INFO_FF) != 0) {
|
||||
frame->id_type = CAN_EXTENDED_IDENTIFIER;
|
||||
frame->flags |= CAN_FRAME_IDE;
|
||||
|
||||
frame->id = FIELD_PREP(GENMASK(28, 21),
|
||||
can_sja1000_read_reg(dev, CAN_SJA1000_XFF_ID1));
|
||||
|
@ -310,8 +308,6 @@ static void can_sja1000_read_frame(const struct device *dev, struct can_frame *f
|
|||
frame->data[i] = can_sja1000_read_reg(dev, CAN_SJA1000_EFF_DATA + i);
|
||||
}
|
||||
} else {
|
||||
frame->id_type = CAN_STANDARD_IDENTIFIER;
|
||||
|
||||
frame->id = FIELD_PREP(GENMASK(10, 3),
|
||||
can_sja1000_read_reg(dev, CAN_SJA1000_XFF_ID1));
|
||||
frame->id |= FIELD_PREP(GENMASK(2, 0),
|
||||
|
@ -330,17 +326,17 @@ void can_sja1000_write_frame(const struct device *dev, const struct can_frame *f
|
|||
|
||||
info = CAN_SJA1000_FRAME_INFO_DLC_PREP(frame->dlc);
|
||||
|
||||
if (frame->rtr == CAN_REMOTEREQUEST) {
|
||||
if ((frame->flags & CAN_FRAME_RTR) != 0) {
|
||||
info |= CAN_SJA1000_FRAME_INFO_RTR;
|
||||
}
|
||||
|
||||
if (frame->id_type == CAN_EXTENDED_IDENTIFIER) {
|
||||
if ((frame->flags & CAN_FRAME_IDE) != 0) {
|
||||
info |= CAN_SJA1000_FRAME_INFO_FF;
|
||||
}
|
||||
|
||||
can_sja1000_write_reg(dev, CAN_SJA1000_FRAME_INFO, info);
|
||||
|
||||
if (frame->id_type == CAN_EXTENDED_IDENTIFIER) {
|
||||
if ((frame->flags & CAN_FRAME_IDE) != 0) {
|
||||
can_sja1000_write_reg(dev, CAN_SJA1000_XFF_ID1,
|
||||
FIELD_GET(GENMASK(28, 21), frame->id));
|
||||
can_sja1000_write_reg(dev, CAN_SJA1000_XFF_ID2,
|
||||
|
@ -379,6 +375,11 @@ int can_sja1000_send(const struct device *dev, const struct can_frame *frame, k_
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ((frame->flags & ~(CAN_FRAME_IDE | CAN_FRAME_RTR)) != 0) {
|
||||
LOG_ERR("unsupported CAN frame flags 0x%02x", frame->flags);
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
if (!data->started) {
|
||||
return -ENETDOWN;
|
||||
}
|
||||
|
@ -425,6 +426,11 @@ int can_sja1000_add_rx_filter(const struct device *dev, can_rx_callback_t callba
|
|||
int filter_id = -ENOSPC;
|
||||
int i;
|
||||
|
||||
if ((filter->flags & ~(CAN_FILTER_IDE | CAN_FILTER_DATA | CAN_FILTER_RTR)) != 0) {
|
||||
LOG_ERR("unsupported CAN filter flags 0x%02x", filter->flags);
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(data->filters); i++) {
|
||||
if (!atomic_test_and_set_bit(data->rx_allocs, i)) {
|
||||
filter_id = i;
|
||||
|
@ -534,10 +540,10 @@ void can_sja1000_set_state_change_callback(const struct device *dev,
|
|||
data->state_change_cb_data = user_data;
|
||||
}
|
||||
|
||||
int can_sja1000_get_max_filters(const struct device *dev, enum can_ide id_type)
|
||||
int can_sja1000_get_max_filters(const struct device *dev, bool ide)
|
||||
{
|
||||
ARG_UNUSED(dev);
|
||||
ARG_UNUSED(id_type);
|
||||
ARG_UNUSED(ide);
|
||||
|
||||
return CONFIG_CAN_MAX_FILTER;
|
||||
}
|
||||
|
|
|
@ -146,7 +146,7 @@ int can_sja1000_get_state(const struct device *dev, enum can_state *state,
|
|||
void can_sja1000_set_state_change_callback(const struct device *dev,
|
||||
can_state_change_callback_t callback, void *user_data);
|
||||
|
||||
int can_sja1000_get_max_filters(const struct device *dev, enum can_ide id_type);
|
||||
int can_sja1000_get_max_filters(const struct device *dev, bool ide);
|
||||
|
||||
int can_sja1000_get_max_bitrate(const struct device *dev, uint32_t *max_bitrate);
|
||||
|
||||
|
|
|
@ -68,15 +68,19 @@ static void can_stm32_signal_tx_complete(const struct device *dev, struct can_st
|
|||
|
||||
static void can_stm32_rx_fifo_pop(CAN_FIFOMailBox_TypeDef *mbox, struct can_frame *frame)
|
||||
{
|
||||
memset(frame, 0, sizeof(*frame));
|
||||
|
||||
if (mbox->RIR & CAN_RI0R_IDE) {
|
||||
frame->id = mbox->RIR >> CAN_RI0R_EXID_Pos;
|
||||
frame->id_type = CAN_EXTENDED_IDENTIFIER;
|
||||
frame->flags |= CAN_FRAME_IDE;
|
||||
} else {
|
||||
frame->id = mbox->RIR >> CAN_RI0R_STID_Pos;
|
||||
frame->id_type = CAN_STANDARD_IDENTIFIER;
|
||||
frame->id = mbox->RIR >> CAN_RI0R_STID_Pos;
|
||||
}
|
||||
|
||||
if ((mbox->RIR & CAN_RI0R_RTR) != 0) {
|
||||
frame->flags |= CAN_FRAME_RTR;
|
||||
}
|
||||
|
||||
frame->rtr = mbox->RIR & CAN_RI0R_RTR ? CAN_REMOTEREQUEST : CAN_DATAFRAME;
|
||||
frame->dlc = mbox->RDTR & (CAN_RDT0R_DLC >> CAN_RDT0R_DLC_Pos);
|
||||
frame->data_32[0] = mbox->RDLR;
|
||||
frame->data_32[1] = mbox->RDHR;
|
||||
|
@ -544,14 +548,14 @@ static int can_stm32_get_max_bitrate(const struct device *dev, uint32_t *max_bit
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int can_stm32_get_max_filters(const struct device *dev, enum can_ide id_type)
|
||||
static int can_stm32_get_max_filters(const struct device *dev, bool ide)
|
||||
{
|
||||
ARG_UNUSED(dev);
|
||||
|
||||
if (id_type == CAN_STANDARD_IDENTIFIER) {
|
||||
return CONFIG_CAN_MAX_STD_ID_FILTER;
|
||||
} else {
|
||||
if (ide) {
|
||||
return CONFIG_CAN_MAX_EXT_ID_FILTER;
|
||||
} else {
|
||||
return CONFIG_CAN_MAX_STD_ID_FILTER;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -741,9 +745,8 @@ static int can_stm32_send(const struct device *dev, const struct can_frame *fram
|
|||
"Remote Frame: %s"
|
||||
, frame->dlc, dev->name
|
||||
, frame->id
|
||||
, frame->id_type == CAN_STANDARD_IDENTIFIER ?
|
||||
"standard" : "extended"
|
||||
, frame->rtr == CAN_DATAFRAME ? "no" : "yes");
|
||||
, (frame->flags & CAN_FRAME_IDE) != 0 ? "extended" : "standard"
|
||||
, (frame->flags & CAN_FRAME_RTR) != 0 ? "yes" : "no");
|
||||
|
||||
__ASSERT_NO_MSG(callback != NULL);
|
||||
__ASSERT(frame->dlc == 0U || frame->data != NULL, "Dataptr is null");
|
||||
|
@ -753,6 +756,11 @@ static int can_stm32_send(const struct device *dev, const struct can_frame *fram
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ((frame->flags & ~(CAN_FRAME_IDE | CAN_FRAME_RTR)) != 0) {
|
||||
LOG_ERR("unsupported CAN frame flags 0x%02x", frame->flags);
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
if (!data->started) {
|
||||
return -ENETDOWN;
|
||||
}
|
||||
|
@ -793,14 +801,14 @@ static int can_stm32_send(const struct device *dev, const struct can_frame *fram
|
|||
/* mailbox identifier register setup */
|
||||
mailbox->TIR &= CAN_TI0R_TXRQ;
|
||||
|
||||
if (frame->id_type == CAN_STANDARD_IDENTIFIER) {
|
||||
mailbox->TIR |= (frame->id << CAN_TI0R_STID_Pos);
|
||||
} else {
|
||||
if ((frame->flags & CAN_FRAME_IDE) != 0) {
|
||||
mailbox->TIR |= (frame->id << CAN_TI0R_EXID_Pos)
|
||||
| CAN_TI0R_IDE;
|
||||
} else {
|
||||
mailbox->TIR |= (frame->id << CAN_TI0R_STID_Pos);
|
||||
}
|
||||
|
||||
if (frame->rtr == CAN_REMOTEREQUEST) {
|
||||
if ((frame->flags & CAN_FRAME_RTR) != 0) {
|
||||
mailbox->TIR |= CAN_TI1R_RTR;
|
||||
}
|
||||
|
||||
|
@ -817,10 +825,12 @@ static int can_stm32_send(const struct device *dev, const struct can_frame *fram
|
|||
}
|
||||
|
||||
static void can_stm32_set_filter_bank(int filter_id, CAN_FilterRegister_TypeDef *filter_reg,
|
||||
enum can_ide type, uint32_t id, uint32_t mask)
|
||||
bool ide, uint32_t id, uint32_t mask)
|
||||
{
|
||||
switch (type) {
|
||||
case CAN_STANDARD_IDENTIFIER:
|
||||
if (ide) {
|
||||
filter_reg->FR1 = id;
|
||||
filter_reg->FR2 = mask;
|
||||
} else {
|
||||
if ((filter_id - CONFIG_CAN_MAX_EXT_ID_FILTER) % 2 == 0) {
|
||||
/* even std filter id: first 1/2 bank */
|
||||
filter_reg->FR1 = id | (mask << 16);
|
||||
|
@ -828,40 +838,41 @@ static void can_stm32_set_filter_bank(int filter_id, CAN_FilterRegister_TypeDef
|
|||
/* uneven std filter id: first 1/2 bank */
|
||||
filter_reg->FR2 = id | (mask << 16);
|
||||
}
|
||||
break;
|
||||
case CAN_EXTENDED_IDENTIFIER:
|
||||
filter_reg->FR1 = id;
|
||||
filter_reg->FR2 = mask;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static inline uint32_t can_stm32_filter_to_std_mask(const struct can_filter *filter)
|
||||
{
|
||||
return (filter->id_mask << CAN_STM32_FIRX_STD_ID_POS) |
|
||||
(filter->rtr_mask << CAN_STM32_FIRX_STD_RTR_POS) |
|
||||
(1U << CAN_STM32_FIRX_STD_IDE_POS);
|
||||
uint32_t rtr_mask = (filter->flags & (CAN_FILTER_DATA | CAN_FILTER_RTR)) !=
|
||||
(CAN_FILTER_DATA | CAN_FILTER_RTR) ? 1U : 0U;
|
||||
|
||||
return (filter->mask << CAN_STM32_FIRX_STD_ID_POS) |
|
||||
(rtr_mask << CAN_STM32_FIRX_STD_RTR_POS) |
|
||||
(1U << CAN_STM32_FIRX_STD_IDE_POS);
|
||||
}
|
||||
|
||||
static inline uint32_t can_stm32_filter_to_ext_mask(const struct can_filter *filter)
|
||||
{
|
||||
return (filter->id_mask << CAN_STM32_FIRX_EXT_EXT_ID_POS) |
|
||||
(filter->rtr_mask << CAN_STM32_FIRX_EXT_RTR_POS) |
|
||||
(1U << CAN_STM32_FIRX_EXT_IDE_POS);
|
||||
uint32_t rtr_mask = (filter->flags & (CAN_FILTER_DATA | CAN_FILTER_RTR)) !=
|
||||
(CAN_FILTER_DATA | CAN_FILTER_RTR) ? 1U : 0U;
|
||||
|
||||
return (filter->mask << CAN_STM32_FIRX_EXT_EXT_ID_POS) |
|
||||
(rtr_mask << CAN_STM32_FIRX_EXT_RTR_POS) |
|
||||
(1U << CAN_STM32_FIRX_EXT_IDE_POS);
|
||||
}
|
||||
|
||||
static inline uint32_t can_stm32_filter_to_std_id(const struct can_filter *filter)
|
||||
{
|
||||
return (filter->id << CAN_STM32_FIRX_STD_ID_POS) |
|
||||
(filter->rtr << CAN_STM32_FIRX_STD_RTR_POS);
|
||||
|
||||
(((filter->flags & CAN_FILTER_RTR) != 0) ? (1U << CAN_STM32_FIRX_STD_RTR_POS) : 0U);
|
||||
}
|
||||
|
||||
static inline uint32_t can_stm32_filter_to_ext_id(const struct can_filter *filter)
|
||||
{
|
||||
return (filter->id << CAN_STM32_FIRX_EXT_EXT_ID_POS) |
|
||||
(filter->rtr << CAN_STM32_FIRX_EXT_RTR_POS) |
|
||||
(1U << CAN_STM32_FIRX_EXT_IDE_POS);
|
||||
return (filter->id << CAN_STM32_FIRX_EXT_EXT_ID_POS) |
|
||||
(((filter->flags & CAN_FILTER_RTR) != 0) ?
|
||||
(1U << CAN_STM32_FIRX_EXT_RTR_POS) : 0U) |
|
||||
(1U << CAN_STM32_FIRX_EXT_IDE_POS);
|
||||
}
|
||||
|
||||
static inline int can_stm32_set_filter(const struct device *dev, const struct can_filter *filter)
|
||||
|
@ -880,17 +891,7 @@ static inline int can_stm32_set_filter(const struct device *dev, const struct ca
|
|||
bank_offset = CAN_STM32_NUM_FILTER_BANKS;
|
||||
}
|
||||
|
||||
if (filter->id_type == CAN_STANDARD_IDENTIFIER) {
|
||||
for (int i = 0; i < CONFIG_CAN_MAX_STD_ID_FILTER; i++) {
|
||||
if (data->rx_cb_std[i] == NULL) {
|
||||
id = can_stm32_filter_to_std_id(filter);
|
||||
mask = can_stm32_filter_to_std_mask(filter);
|
||||
filter_id = CONFIG_CAN_MAX_EXT_ID_FILTER + i;
|
||||
bank_num = bank_offset + CONFIG_CAN_MAX_EXT_ID_FILTER + i / 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ((filter->flags & CAN_FILTER_IDE) != 0) {
|
||||
for (int i = 0; i < CONFIG_CAN_MAX_EXT_ID_FILTER; i++) {
|
||||
if (data->rx_cb_ext[i] == NULL) {
|
||||
id = can_stm32_filter_to_ext_id(filter);
|
||||
|
@ -900,17 +901,28 @@ static inline int can_stm32_set_filter(const struct device *dev, const struct ca
|
|||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < CONFIG_CAN_MAX_STD_ID_FILTER; i++) {
|
||||
if (data->rx_cb_std[i] == NULL) {
|
||||
id = can_stm32_filter_to_std_id(filter);
|
||||
mask = can_stm32_filter_to_std_mask(filter);
|
||||
filter_id = CONFIG_CAN_MAX_EXT_ID_FILTER + i;
|
||||
bank_num = bank_offset + CONFIG_CAN_MAX_EXT_ID_FILTER + i / 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (filter_id != -ENOSPC) {
|
||||
LOG_DBG("Adding filter_id %d, CAN ID: 0x%x, mask: 0x%x",
|
||||
filter_id, filter->id, filter->id_mask);
|
||||
filter_id, filter->id, filter->mask);
|
||||
|
||||
/* set the filter init mode */
|
||||
can->FMR |= CAN_FMR_FINIT;
|
||||
|
||||
can_stm32_set_filter_bank(filter_id, &can->sFilterRegister[bank_num],
|
||||
filter->id_type, id, mask);
|
||||
(filter->flags & CAN_FILTER_IDE) != 0,
|
||||
id, mask);
|
||||
|
||||
can->FA1R |= 1U << bank_num;
|
||||
can->FMR &= ~(CAN_FMR_FINIT);
|
||||
|
@ -940,17 +952,22 @@ static int can_stm32_add_rx_filter(const struct device *dev, can_rx_callback_t c
|
|||
struct can_stm32_data *data = dev->data;
|
||||
int filter_id;
|
||||
|
||||
if ((filter->flags & ~(CAN_FILTER_IDE | CAN_FILTER_DATA | CAN_FILTER_RTR)) != 0) {
|
||||
LOG_ERR("unsupported CAN filter flags 0x%02x", filter->flags);
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
k_mutex_lock(&filter_mutex, K_FOREVER);
|
||||
k_mutex_lock(&data->inst_mutex, K_FOREVER);
|
||||
|
||||
filter_id = can_stm32_set_filter(dev, filter);
|
||||
if (filter_id >= 0) {
|
||||
if (filter->id_type == CAN_STANDARD_IDENTIFIER) {
|
||||
data->rx_cb_std[filter_id - CONFIG_CAN_MAX_EXT_ID_FILTER] = cb;
|
||||
data->cb_arg_std[filter_id - CONFIG_CAN_MAX_EXT_ID_FILTER] = cb_arg;
|
||||
} else {
|
||||
if ((filter->flags & CAN_FILTER_IDE) != 0) {
|
||||
data->rx_cb_ext[filter_id] = cb;
|
||||
data->cb_arg_ext[filter_id] = cb_arg;
|
||||
} else {
|
||||
data->rx_cb_std[filter_id - CONFIG_CAN_MAX_EXT_ID_FILTER] = cb;
|
||||
data->cb_arg_std[filter_id - CONFIG_CAN_MAX_EXT_ID_FILTER] = cb_arg;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -965,7 +982,7 @@ static void can_stm32_remove_rx_filter(const struct device *dev, int filter_id)
|
|||
const struct can_stm32_config *cfg = dev->config;
|
||||
struct can_stm32_data *data = dev->data;
|
||||
CAN_TypeDef *can = cfg->master_can;
|
||||
enum can_ide filter_type;
|
||||
bool ide;
|
||||
int bank_offset = 0;
|
||||
int bank_num;
|
||||
bool bank_unused;
|
||||
|
@ -980,7 +997,7 @@ static void can_stm32_remove_rx_filter(const struct device *dev, int filter_id)
|
|||
}
|
||||
|
||||
if (filter_id < CONFIG_CAN_MAX_EXT_ID_FILTER) {
|
||||
filter_type = CAN_EXTENDED_IDENTIFIER;
|
||||
ide = true;
|
||||
bank_num = bank_offset + filter_id;
|
||||
|
||||
data->rx_cb_ext[filter_id] = NULL;
|
||||
|
@ -990,7 +1007,7 @@ static void can_stm32_remove_rx_filter(const struct device *dev, int filter_id)
|
|||
} else {
|
||||
int filter_index = filter_id - CONFIG_CAN_MAX_EXT_ID_FILTER;
|
||||
|
||||
filter_type = CAN_STANDARD_IDENTIFIER;
|
||||
ide = false;
|
||||
bank_num = bank_offset + CONFIG_CAN_MAX_EXT_ID_FILTER +
|
||||
(filter_id - CONFIG_CAN_MAX_EXT_ID_FILTER) / 2;
|
||||
|
||||
|
@ -1006,12 +1023,12 @@ static void can_stm32_remove_rx_filter(const struct device *dev, int filter_id)
|
|||
}
|
||||
}
|
||||
|
||||
LOG_DBG("Removing filter_id %d, type %d", filter_id, (uint32_t)filter_type);
|
||||
LOG_DBG("Removing filter_id %d, ide %d", filter_id, ide);
|
||||
|
||||
can->FMR |= CAN_FMR_FINIT;
|
||||
|
||||
can_stm32_set_filter_bank(filter_id, &can->sFilterRegister[bank_num],
|
||||
filter_type, 0, 0xFFFFFFFF);
|
||||
ide, 0, 0xFFFFFFFF);
|
||||
|
||||
if (bank_unused) {
|
||||
can->FA1R &= ~(1U << bank_num);
|
||||
|
|
|
@ -21,15 +21,19 @@
|
|||
static inline bool can_utils_filter_match(const struct can_frame *frame,
|
||||
struct can_filter *filter)
|
||||
{
|
||||
if (frame->id_type != filter->id_type) {
|
||||
if (((frame->flags & CAN_FRAME_IDE) != 0) && ((filter->flags & CAN_FILTER_IDE) == 0)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((frame->rtr ^ filter->rtr) & filter->rtr_mask) {
|
||||
if (((frame->flags & CAN_FRAME_RTR) == 0) && (filter->flags & CAN_FILTER_DATA) == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((frame->id ^ filter->id) & filter->id_mask) {
|
||||
if (((frame->flags & CAN_FRAME_RTR) != 0) && (filter->flags & CAN_FILTER_RTR) == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((frame->id ^ filter->id) & filter->mask) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue