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:
Henrik Brix Andersen 2022-09-30 14:44:16 +02:00 committed by Carles Cufí
commit f8a88cdb27
29 changed files with 661 additions and 626 deletions

View file

@ -152,8 +152,7 @@ a mailbox. When a transmitting mailbox is assigned, sending cannot be canceled.
.. code-block:: C .. code-block:: C
struct can_frame frame = { struct can_frame frame = {
.id_type = CAN_STANDARD_IDENTIFIER, .flags = 0,
.rtr = CAN_DATAFRAME,
.id = 0x123, .id = 0x123,
.dlc = 8, .dlc = 8,
.data = {1,2,3,4,5,6,7,8} .data = {1,2,3,4,5,6,7,8}
@ -187,8 +186,7 @@ occurred. It does not block until the message is sent like the example above.
int send_function(const struct device *can_dev) int send_function(const struct device *can_dev)
{ {
struct can_frame frame = { struct can_frame frame = {
.id_type = CAN_EXTENDED_IDENTIFIER, .flags = CAN_FRAME_IDE,
.rtr = CAN_DATAFRAME,
.id = 0x1234567, .id = 0x1234567,
.dlc = 2 .dlc = 2
}; };
@ -227,10 +225,8 @@ The filter for this example is configured to match the identifier 0x123 exactly.
.. code-block:: C .. code-block:: C
const struct can_filter my_filter = { const struct can_filter my_filter = {
.id_type = CAN_STANDARD_IDENTIFIER, .flags = CAN_FILTER_DATA,
.rtr = CAN_DATAFRAME,
.id = 0x123, .id = 0x123,
.rtr_mask = 1,
.id_mask = CAN_STD_ID_MASK .id_mask = CAN_STD_ID_MASK
}; };
int filter_id; int filter_id;
@ -252,10 +248,8 @@ The filter for this example is configured to match the extended identifier
.. code-block:: C .. code-block:: C
const struct can_filter my_filter = { const struct can_filter my_filter = {
.id_type = CAN_EXTENDED_IDENTIFIER, .flags = CAN_FILTER_DATA | CAN_FILTER_IDE,
.rtr = CAN_DATAFRAME,
.id = 0x1234567, .id = 0x1234567,
.rtr_mask = 1,
.id_mask = CAN_EXT_ID_MASK .id_mask = CAN_EXT_ID_MASK
}; };
CAN_MSGQ_DEFINE(my_can_msgq, 2); CAN_MSGQ_DEFINE(my_can_msgq, 2);

View file

@ -129,12 +129,12 @@ static inline int z_vrfy_can_set_bitrate_data(const struct device *dev,
#endif /* CONFIG_CAN_FD_MODE */ #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 */ /* Optional API function */
Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_CAN)); 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> #include <syscalls/can_get_max_filters_mrsh.c>

View file

@ -33,11 +33,14 @@ struct can_loopback_filter {
struct can_loopback_data { struct can_loopback_data {
struct can_loopback_filter filters[CONFIG_CAN_MAX_FILTER]; struct can_loopback_filter filters[CONFIG_CAN_MAX_FILTER];
struct k_mutex mtx; struct k_mutex mtx;
bool loopback;
struct k_msgq tx_msgq; struct k_msgq tx_msgq;
char msgq_buffer[CONFIG_CAN_LOOPBACK_TX_MSGQ_SIZE * sizeof(struct can_loopback_frame)]; char msgq_buffer[CONFIG_CAN_LOOPBACK_TX_MSGQ_SIZE * sizeof(struct can_loopback_frame)];
struct k_thread tx_thread_data; struct k_thread tx_thread_data;
bool started; bool started;
bool loopback;
#ifdef CONFIG_CAN_FD_MODE
bool fd;
#endif /* CONFIG_CAN_FD_MODE */
K_KERNEL_STACK_MEMBER(tx_thread_stack, K_KERNEL_STACK_MEMBER(tx_thread_stack,
CONFIG_CAN_LOOPBACK_TX_THREAD_STACK_SIZE); 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", LOG_DBG("Receiving %d bytes. Id: 0x%x, ID type: %s %s",
frame->dlc, frame->id, frame->dlc, frame->id,
frame->id_type == CAN_STANDARD_IDENTIFIER ? (frame->flags & CAN_FRAME_IDE) != 0 ? "extended" : "standard",
"standard" : "extended", (frame->flags & CAN_FRAME_RTR) != 0 ? ", RTR frame" : "");
frame->rtr == CAN_DATAFRAME ? "" : ", RTR frame");
filter->rx_cb(dev, &frame_tmp, filter->cb_arg); 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", LOG_DBG("Sending %d bytes on %s. Id: 0x%x, ID type: %s %s",
frame->dlc, dev->name, frame->id, frame->dlc, dev->name, frame->id,
frame->id_type == CAN_STANDARD_IDENTIFIER ? (frame->flags & CAN_FRAME_IDE) != 0 ? "extended" : "standard",
"standard" : "extended", (frame->flags & CAN_FRAME_RTR) != 0 ? ", RTR frame" : "");
frame->rtr == CAN_DATAFRAME ? "" : ", RTR frame");
#ifdef CONFIG_CAN_FD_MODE #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; 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) { if (frame->dlc > max_dlc) {
LOG_ERR("DLC of %d exceeds maximum (%d)", 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; struct can_loopback_filter *loopback_filter;
int filter_id; int filter_id;
LOG_DBG("Setting filter ID: 0x%x, mask: 0x%x", filter->id, LOG_DBG("Setting filter ID: 0x%x, mask: 0x%x", filter->id, filter->mask);
filter->id_mask);
LOG_DBG("Filter type: %s ID %s mask", if ((filter->flags & ~(CAN_FILTER_IDE | CAN_FILTER_DATA | CAN_FILTER_RTR)) != 0) {
filter->id_type == CAN_STANDARD_IDENTIFIER ? LOG_ERR("unsupported CAN filter flags 0x%02x", filter->flags);
"standard" : "extended", return -ENOTSUP;
((filter->id_type && (filter->id_mask == CAN_STD_ID_MASK)) || }
(!filter->id_type && (filter->id_mask == CAN_EXT_ID_MASK))) ?
"with" : "without");
k_mutex_lock(&data->mtx, K_FOREVER); k_mutex_lock(&data->mtx, K_FOREVER);
filter_id = get_free_filter(data->filters); 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); LOG_ERR("unsupported mode: 0x%08x", mode);
return -ENOTSUP; return -ENOTSUP;
} }
data->fd = (mode & CAN_MODE_FD) != 0;
#else #else
if ((mode & ~(CAN_MODE_LOOPBACK)) != 0) { if ((mode & ~(CAN_MODE_LOOPBACK)) != 0) {
LOG_ERR("unsupported mode: 0x%08x", mode); 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 */ #endif /* CONFIG_CAN_FD_MODE */
data->loopback = (mode & CAN_MODE_LOOPBACK) != 0 ? 1 : 0; data->loopback = (mode & CAN_MODE_LOOPBACK) != 0;
return 0; return 0;
} }
@ -335,9 +352,9 @@ static int can_loopback_get_core_clock(const struct device *dev, uint32_t *rate)
return 0; 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; return CONFIG_CAN_MAX_FILTER;
} }

View file

@ -21,12 +21,6 @@ LOG_MODULE_REGISTER(can_mcan, CONFIG_CAN_LOG_LEVEL);
#define CAN_INIT_TIMEOUT (100) #define CAN_INIT_TIMEOUT (100)
#define CAN_DIV_CEIL(val, div) (((val) + (div) - 1) / (div)) #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_, static void memcpy32_volatile(volatile void *dst_, const volatile void *src_,
size_t len) size_t len)
{ {
@ -618,7 +612,7 @@ static void can_mcan_get_message(const struct device *dev,
{ {
struct can_mcan_data *data = dev->data; struct can_mcan_data *data = dev->data;
uint32_t get_idx, filt_idx; uint32_t get_idx, filt_idx;
struct can_frame frame; struct can_frame frame = {0};
can_rx_callback_t cb; can_rx_callback_t cb;
int data_length; int data_length;
void *cb_arg; void *cb_arg;
@ -636,18 +630,20 @@ static void can_mcan_get_message(const struct device *dev,
memcpy32_volatile(&hdr, &fifo[get_idx].hdr, memcpy32_volatile(&hdr, &fifo[get_idx].hdr,
sizeof(struct can_mcan_rx_fifo_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.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) #if defined(CONFIG_CAN_RX_TIMESTAMP)
frame.timestamp = hdr.rxts; frame.timestamp = hdr.rxts;
#endif #endif
@ -655,39 +651,42 @@ static void can_mcan_get_message(const struct device *dev,
filt_idx = hdr.fidx; filt_idx = hdr.fidx;
if (hdr.xtd != 0) { 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_mask = (data->ext_filt_rtr_mask & BIT(filt_idx)) != 0;
rtr_filter = (data->ext_filt_rtr & BIT(filt_idx)) != 0; rtr_filter = (data->ext_filt_rtr & BIT(filt_idx)) != 0;
} else { } else {
frame.id = hdr.std_id;
rtr_filter_mask = (data->std_filt_rtr_mask & BIT(filt_idx)) != 0; rtr_filter_mask = (data->std_filt_rtr_mask & BIT(filt_idx)) != 0;
rtr_filter = (data->std_filt_rtr & BIT(filt_idx)) != 0; rtr_filter = (data->std_filt_rtr & BIT(filt_idx)) != 0;
} }
if (rtr_filter_mask && (rtr_filter != frame.rtr)) { if (rtr_filter_mask && (rtr_filter != ((frame.flags & CAN_FRAME_RTR) != 0))) {
/* RTR bit does not match filter RTR mask and bit, drop frame */ /* RTR bit does not match filter RTR mask, drop frame */
*fifo_ack_reg = get_idx; *fifo_ack_reg = get_idx;
continue; continue;
} }
data_length = can_dlc_to_bytes(frame.dlc); data_length = can_dlc_to_bytes(frame.dlc);
if (data_length <= sizeof(frame.data)) { 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, sys_cache_data_range((void *)fifo[get_idx].data_32,
ROUND_UP(data_length, sizeof(uint32_t)), ROUND_UP(data_length, sizeof(uint32_t)),
K_CACHE_INVD); K_CACHE_INVD);
memcpy32_volatile(frame.data_32, fifo[get_idx].data_32, memcpy32_volatile(frame.data_32, fifo[get_idx].data_32,
ROUND_UP(data_length, sizeof(uint32_t))); ROUND_UP(data_length, sizeof(uint32_t)));
if (frame.id_type == CAN_STANDARD_IDENTIFIER) { if ((frame.flags & CAN_FRAME_IDE) != 0) {
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 {
LOG_DBG("Frame on filter %d, ID: 0x%x", LOG_DBG("Frame on filter %d, ID: 0x%x",
filt_idx + NUM_STD_FILTER_DATA, filt_idx + NUM_STD_FILTER_DATA,
frame.id); frame.id);
cb = data->rx_cb_ext[filt_idx]; cb = data->rx_cb_ext[filt_idx];
cb_arg = data->cb_arg_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) { if (cb) {
@ -798,15 +797,18 @@ int can_mcan_send(const struct device *dev,
struct can_mcan_msg_sram *msg_ram = data->msg_ram; struct can_mcan_msg_sram *msg_ram = data->msg_ram;
size_t data_length = can_dlc_to_bytes(frame->dlc); size_t data_length = can_dlc_to_bytes(frame->dlc);
struct can_mcan_tx_buffer_hdr tx_hdr = { struct can_mcan_tx_buffer_hdr tx_hdr = {
.rtr = frame->rtr == CAN_REMOTEREQUEST, .rtr = (frame->flags & CAN_FRAME_RTR) != 0 ? 1U : 0U,
.xtd = frame->id_type == CAN_EXTENDED_IDENTIFIER, .xtd = (frame->flags & CAN_FRAME_IDE) != 0 ? 1U : 0U,
.esi = 0, .esi = 0U,
.dlc = frame->dlc, .dlc = frame->dlc,
#ifdef CONFIG_CAN_FD_MODE #ifdef CONFIG_CAN_FD_MODE
.brs = frame->brs == true, .fdf = (frame->flags & CAN_FRAME_FDF) != 0 ? 1U : 0U,
#endif .brs = (frame->flags & CAN_FRAME_BRS) != 0 ? 1U : 0U,
.fdf = frame->fd, #else /* CONFIG_CAN_FD_MODE */
.efc = 1, .fdf = 0U,
.brs = 0U,
#endif /* !CONFIG_CAN_FD_MODE */
.efc = 1U,
}; };
uint32_t put_idx; uint32_t put_idx;
int ret; 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", LOG_DBG("Sending %d bytes. Id: 0x%x, ID type: %s %s %s %s",
data_length, frame->id, data_length, frame->id,
frame->id_type == CAN_STANDARD_IDENTIFIER ? (frame->flags & CAN_FRAME_IDE) != 0 ? "extended" : "standard",
"standard" : "extended", (frame->flags & CAN_FRAME_RTR) != 0 ? "RTR" : "",
frame->rtr == CAN_DATAFRAME ? "" : "RTR", (frame->flags & CAN_FRAME_FDF) != 0 ? "FD frame" : "",
frame->fd == CAN_DATAFRAME ? "" : "FD frame", (frame->flags & CAN_FRAME_BRS) != 0 ? "BRS" : "");
frame->brs == CAN_DATAFRAME ? "" : "BRS");
__ASSERT_NO_MSG(callback != NULL); __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)) { if (data_length > sizeof(frame->data)) {
LOG_ERR("data length (%zu) > max frame data length (%zu)", LOG_ERR("data length (%zu) > max frame data length (%zu)",
data_length, sizeof(frame->data)); data_length, sizeof(frame->data));
return -EINVAL; return -EINVAL;
} }
if (frame->fd != 1 && frame->dlc > MCAN_MAX_DLC) { if ((frame->flags & CAN_FRAME_FDF) != 0) {
LOG_ERR("DLC of %d without fd flag set.", frame->dlc); if (frame->dlc > CANFD_MAX_DLC) {
return -EINVAL; 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) { if (!data->started) {
@ -858,10 +889,10 @@ int can_mcan_send(const struct device *dev,
mm.cnt = data->mm.cnt++; mm.cnt = data->mm.cnt++;
tx_hdr.mm = mm; tx_hdr.mm = mm;
if (frame->id_type == CAN_STANDARD_IDENTIFIER) { if ((frame->flags & CAN_FRAME_IDE) != 0) {
tx_hdr.std_id = frame->id & CAN_STD_ID_MASK;
} else {
tx_hdr.ext_id = frame->id; 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)); 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; 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); ARG_UNUSED(dev);
if (id_type == CAN_STANDARD_IDENTIFIER) { if (ide) {
return NUM_STD_FILTER_DATA;
} else {
return NUM_EXT_FILTER_DATA; 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_msg_sram *msg_ram = data->msg_ram;
struct can_mcan_std_filter filter_element = { struct can_mcan_std_filter filter_element = {
.id1 = filter->id, .id1 = filter->id,
.id2 = filter->id_mask, .id2 = filter->mask,
.sft = CAN_MCAN_SFT_MASKED .sft = CAN_MCAN_SFT_MASKED
}; };
int filter_id; 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); k_mutex_lock(&data->inst_mutex, K_FOREVER);
filter_id = can_mcan_get_free_std(msg_ram->std_filt); 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); 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); data->std_filt_rtr |= (1U << filter_id);
} else { } else {
data->std_filt_rtr &= ~(1U << filter_id); 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); data->std_filt_rtr_mask |= (1U << filter_id);
} else { } else {
data->std_filt_rtr_mask &= ~(1U << filter_id); 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_data *data = dev->data;
struct can_mcan_msg_sram *msg_ram = data->msg_ram; struct can_mcan_msg_sram *msg_ram = data->msg_ram;
struct can_mcan_ext_filter filter_element = { struct can_mcan_ext_filter filter_element = {
.id2 = filter->id_mask, .id2 = filter->mask,
.id1 = filter->id, .id1 = filter->id,
.eft = CAN_MCAN_EFT_MASKED .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); 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); data->ext_filt_rtr |= (1U << filter_id);
} else { } else {
data->ext_filt_rtr &= ~(1U << filter_id); 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); data->ext_filt_rtr_mask |= (1U << filter_id);
} else { } else {
data->ext_filt_rtr_mask &= ~(1U << filter_id); data->ext_filt_rtr_mask &= ~(1U << filter_id);
@ -1035,13 +1073,13 @@ int can_mcan_add_rx_filter(const struct device *dev,
return -EINVAL; return -EINVAL;
} }
if (filter->id_type == CAN_STANDARD_IDENTIFIER) { if ((filter->flags & CAN_FILTER_IDE) != 0) {
filter_id = can_mcan_add_rx_filter_std(dev, callback, user_data, filter);
} else {
filter_id = can_mcan_add_rx_filter_ext(dev, callback, user_data, filter); filter_id = can_mcan_add_rx_filter_ext(dev, callback, user_data, filter);
if (filter_id >= 0) { if (filter_id >= 0) {
filter_id += NUM_STD_FILTER_DATA; filter_id += NUM_STD_FILTER_DATA;
} }
} else {
filter_id = can_mcan_add_rx_filter_std(dev, callback, user_data, filter);
} }
return filter_id; return filter_id;

View file

@ -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, k_timeout_t timeout, can_tx_callback_t callback,
void *user_data); 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, int can_mcan_add_rx_filter(const struct device *dev,
can_rx_callback_t callback, void *user_data, can_rx_callback_t callback, void *user_data,

View file

@ -222,20 +222,20 @@ static void mcp2515_convert_canframe_to_mcp2515frame(const struct can_frame
uint8_t dlc; uint8_t dlc;
uint8_t data_idx = 0U; uint8_t data_idx = 0U;
if (source->id_type == CAN_STANDARD_IDENTIFIER) { if ((source->flags & CAN_FRAME_IDE) != 0) {
target[MCP2515_FRAME_OFFSET_SIDH] = source->id >> 3;
target[MCP2515_FRAME_OFFSET_SIDL] =
(source->id & 0x07) << 5;
} else {
target[MCP2515_FRAME_OFFSET_SIDH] = source->id >> 21; target[MCP2515_FRAME_OFFSET_SIDH] = source->id >> 21;
target[MCP2515_FRAME_OFFSET_SIDL] = target[MCP2515_FRAME_OFFSET_SIDL] =
(((source->id >> 18) & 0x07) << 5) | (BIT(3)) | (((source->id >> 18) & 0x07) << 5) | (BIT(3)) |
((source->id >> 16) & 0x03); ((source->id >> 16) & 0x03);
target[MCP2515_FRAME_OFFSET_EID8] = source->id >> 8; target[MCP2515_FRAME_OFFSET_EID8] = source->id >> 8;
target[MCP2515_FRAME_OFFSET_EID0] = source->id; 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; dlc = (source->dlc) & 0x0F;
target[MCP2515_FRAME_OFFSET_DLC] = rtr | dlc; 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; uint8_t data_idx = 0U;
memset(target, 0, sizeof(*target));
if (source[MCP2515_FRAME_OFFSET_SIDL] & BIT(3)) { if (source[MCP2515_FRAME_OFFSET_SIDL] & BIT(3)) {
target->id_type = CAN_EXTENDED_IDENTIFIER; target->flags |= CAN_FRAME_IDE;
target->id = target->id =
(source[MCP2515_FRAME_OFFSET_SIDH] << 21) | (source[MCP2515_FRAME_OFFSET_SIDH] << 21) |
((source[MCP2515_FRAME_OFFSET_SIDL] >> 5) << 18) | ((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_EID8] << 8) |
source[MCP2515_FRAME_OFFSET_EID0]; source[MCP2515_FRAME_OFFSET_EID0];
} else { } else {
target->id_type = CAN_STANDARD_IDENTIFIER;
target->id = (source[MCP2515_FRAME_OFFSET_SIDH] << 3) | target->id = (source[MCP2515_FRAME_OFFSET_SIDH] << 3) |
(source[MCP2515_FRAME_OFFSET_SIDL] >> 5); (source[MCP2515_FRAME_OFFSET_SIDL] >> 5);
} }
target->dlc = source[MCP2515_FRAME_OFFSET_DLC] & 0x0F; 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++) { for (; data_idx < CAN_MAX_DLC; data_idx++) {
target->data[data_idx] = source[MCP2515_FRAME_OFFSET_D0 + 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; 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; return CONFIG_CAN_MAX_FILTER;
} }
@ -577,6 +580,11 @@ static int mcp2515_send(const struct device *dev,
return -EINVAL; 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) { if (!dev_data->started) {
return -ENETDOWN; 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"); __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); k_mutex_lock(&dev_data->mutex, K_FOREVER);
/* find free filter */ /* find free filter */

View file

@ -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); 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; 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, static void mcux_flexcan_from_can_frame(const struct can_frame *src,
flexcan_frame_t *dest) flexcan_frame_t *dest)
{ {
if (src->id_type == CAN_STANDARD_IDENTIFIER) { memset(dest, 0, sizeof(*dest));
dest->format = kFLEXCAN_FrameFormatStandard;
dest->id = FLEXCAN_ID_STD(src->id); if ((src->flags & CAN_FRAME_IDE) != 0) {
} else {
dest->format = kFLEXCAN_FrameFormatExtend; dest->format = kFLEXCAN_FrameFormatExtend;
dest->id = FLEXCAN_ID_EXT(src->id); dest->id = FLEXCAN_ID_EXT(src->id);
} else {
dest->format = kFLEXCAN_FrameFormatStandard;
dest->id = FLEXCAN_ID_STD(src->id);
} }
if (src->rtr == CAN_DATAFRAME) { if ((src->flags & CAN_FRAME_RTR) != 0) {
dest->type = kFLEXCAN_FrameTypeData;
} else {
dest->type = kFLEXCAN_FrameTypeRemote; dest->type = kFLEXCAN_FrameTypeRemote;
} else {
dest->type = kFLEXCAN_FrameTypeData;
} }
dest->length = src->dlc; 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, static void mcux_flexcan_to_can_frame(const flexcan_frame_t *src,
struct can_frame *dest) struct can_frame *dest)
{ {
memset(dest, 0, sizeof(*dest));
if (src->format == kFLEXCAN_FrameFormatStandard) { if (src->format == kFLEXCAN_FrameFormatStandard) {
dest->id_type = CAN_STANDARD_IDENTIFIER;
dest->id = FLEXCAN_ID_TO_CAN_ID_STD(src->id); dest->id = FLEXCAN_ID_TO_CAN_ID_STD(src->id);
} else { } else {
dest->id_type = CAN_EXTENDED_IDENTIFIER; dest->flags |= CAN_FRAME_IDE;
dest->id = FLEXCAN_ID_TO_CAN_ID_EXT(src->id); dest->id = FLEXCAN_ID_TO_CAN_ID_EXT(src->id);
} }
if (src->type == kFLEXCAN_FrameTypeData) { if (src->type == kFLEXCAN_FrameTypeRemote) {
dest->rtr = CAN_DATAFRAME; dest->flags |= CAN_FRAME_RTR;
} else {
dest->rtr = CAN_REMOTEREQUEST;
} }
dest->dlc = src->length; 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, flexcan_rx_mb_config_t *dest,
uint32_t *mask) uint32_t *mask)
{ {
if (src->id_type == CAN_STANDARD_IDENTIFIER) { static const uint32_t ide_mask = 1U;
dest->format = kFLEXCAN_FrameFormatStandard; uint32_t rtr_mask = (src->flags & (CAN_FILTER_DATA | CAN_FILTER_RTR)) !=
dest->id = FLEXCAN_ID_STD(src->id); (CAN_FILTER_DATA | CAN_FILTER_RTR) ? 1U : 0U;
*mask = FLEXCAN_RX_MB_STD_MASK(src->id_mask, src->rtr_mask, 1);
} else { if ((src->flags & CAN_FILTER_IDE) != 0) {
dest->format = kFLEXCAN_FrameFormatExtend; dest->format = kFLEXCAN_FrameFormatExtend;
dest->id = FLEXCAN_ID_EXT(src->id); 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) { if ((src->flags & CAN_FILTER_RTR) != 0) {
dest->type = kFLEXCAN_FrameTypeData;
} else {
dest->type = kFLEXCAN_FrameTypeRemote; dest->type = kFLEXCAN_FrameTypeRemote;
} else {
dest->type = kFLEXCAN_FrameTypeData;
} }
} }
@ -431,6 +436,11 @@ static int mcux_flexcan_send(const struct device *dev,
return -EINVAL; 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) { if (!data->started) {
return -ENETDOWN; return -ENETDOWN;
} }
@ -481,6 +491,11 @@ static int mcux_flexcan_add_rx_filter(const struct device *dev,
__ASSERT_NO_MSG(callback); __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); k_mutex_lock(&data->rx_mutex, K_FOREVER);
/* Find and allocate RX message buffer */ /* Find and allocate RX message buffer */

View file

@ -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", LOG_DBG("Received %d bytes. Id: 0x%x, ID type: %s %s",
frame.dlc, frame.id, frame.dlc, frame.id,
frame.id_type == CAN_STANDARD_IDENTIFIER ? (frame.flags & CAN_FRAME_IDE) != 0 ? "extended" : "standard",
"standard" : "extended", (frame.flags & CAN_FRAME_RTR) != 0 ? ", RTR frame" : "");
frame.rtr == CAN_DATAFRAME ? "" : ", RTR frame");
dispatch_frame(dev, &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", LOG_DBG("Sending %d bytes on %s. Id: 0x%x, ID type: %s %s",
frame->dlc, dev->name, frame->id, frame->dlc, dev->name, frame->id,
frame->id_type == CAN_STANDARD_IDENTIFIER ? (frame->flags & CAN_FRAME_IDE) != 0 ? "extended" : "standard",
"standard" : "extended", (frame->flags & CAN_FRAME_RTR) != 0 ? ", RTR frame" : "");
frame->rtr == CAN_DATAFRAME ? "" : ", RTR frame");
__ASSERT_NO_MSG(callback != NULL); __ASSERT_NO_MSG(callback != NULL);
#ifdef CONFIG_CAN_FD_MODE #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; max_dlc = CANFD_MAX_DLC;
mtu = CANFD_MTU; 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) { if (frame->dlc > max_dlc) {
LOG_ERR("DLC of %d exceeds maximum (%d)", 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; int filter_id = -ENOSPC;
LOG_DBG("Setting filter ID: 0x%x, mask: 0x%x", filter->id, LOG_DBG("Setting filter ID: 0x%x, mask: 0x%x", filter->id,
filter->id_mask); filter->mask);
LOG_DBG("Filter type: %s ID %s mask",
filter->id_type == CAN_STANDARD_IDENTIFIER ? if ((filter->flags & ~(CAN_FILTER_IDE | CAN_FILTER_DATA | CAN_FILTER_RTR)) != 0) {
"standard" : "extended", LOG_ERR("unsupported CAN filter flags 0x%02x", filter->flags);
((filter->id_type && (filter->id_mask == CAN_STD_ID_MASK)) || return -ENOTSUP;
(!filter->id_type && (filter->id_mask == CAN_EXT_ID_MASK))) ? }
"with" : "without");
k_mutex_lock(&data->filter_mutex, K_FOREVER); 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; 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; return CONFIG_CAN_MAX_FILTER;
} }

View file

@ -389,23 +389,20 @@ static void can_rcar_rx_isr(const struct device *dev)
{ {
const struct can_rcar_cfg *config = dev->config; const struct can_rcar_cfg *config = dev->config;
struct can_rcar_data *data = dev->data; struct can_rcar_data *data = dev->data;
struct can_frame frame; struct can_frame frame = {0};
uint32_t val; uint32_t val;
int i; int i;
val = sys_read32(config->reg_addr + RCAR_CAN_MB_60); val = sys_read32(config->reg_addr + RCAR_CAN_MB_60);
if (val & RCAR_CAN_MB_IDE) { 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; frame.id = val & RCAR_CAN_MB_EID_MASK;
} else { } else {
frame.id_type = CAN_STANDARD_IDENTIFIER;
frame.id = (val & RCAR_CAN_MB_SID_MASK) >> RCAR_CAN_MB_SID_SHIFT; frame.id = (val & RCAR_CAN_MB_SID_MASK) >> RCAR_CAN_MB_SID_SHIFT;
} }
if (val & RCAR_CAN_MB_RTR) { if (val & RCAR_CAN_MB_RTR) {
frame.rtr = CAN_REMOTEREQUEST; frame.flags |= CAN_FRAME_RTR;
} else {
frame.rtr = CAN_DATAFRAME;
} }
frame.dlc = sys_read16(config->reg_addr + 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" "Remote Frame: %s"
, frame->dlc, dev->name , frame->dlc, dev->name
, frame->id , frame->id
, frame->id_type == CAN_STANDARD_IDENTIFIER ? , (frame->flags & CAN_FRAME_IDE) != 0 ?
"standard" : "extended" "extended" : "standard"
, frame->rtr == CAN_DATAFRAME ? "no" : "yes"); , (frame->flags & CAN_FRAME_RTR) != 0 ? "yes" : "no");
__ASSERT_NO_MSG(callback != NULL); __ASSERT_NO_MSG(callback != NULL);
__ASSERT(frame->dlc == 0U || frame->data != NULL, "Dataptr is 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; 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) { if (!data->started) {
return -ENETDOWN; return -ENETDOWN;
} }
@ -888,13 +890,13 @@ static int can_rcar_send(const struct device *dev, const struct can_frame *frame
data->tx_head = 0; data->tx_head = 0;
} }
if (frame->id_type == CAN_STANDARD_IDENTIFIER) { if ((frame->flags & CAN_FRAME_IDE) != 0) {
identifier = frame->id << RCAR_CAN_MB_SID_SHIFT;
} else {
identifier = frame->id | RCAR_CAN_MB_IDE; 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; 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; struct can_rcar_data *data = dev->data;
int filter_id; 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; return -ENOTSUP;
} }
@ -1121,9 +1124,9 @@ static int can_rcar_get_core_clock(const struct device *dev, uint32_t *rate)
return 0; 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; return CONFIG_CAN_RCAR_MAX_FILTER;
} }

View file

@ -72,29 +72,29 @@ static void can_shell_print_frame(const struct shell *sh, const struct can_frame
#ifdef CONFIG_CAN_FD_MODE #ifdef CONFIG_CAN_FD_MODE
/* Flags */ /* 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 */ #endif /* CONFIG_CAN_FD_MODE */
/* CAN ID */ /* CAN ID */
shell_fprintf(sh, SHELL_NORMAL, "%*s%0*x ", shell_fprintf(sh, SHELL_NORMAL, "%*s%0*x ",
frame->id_type == CAN_STANDARD_IDENTIFIER ? 5 : 0, "", (frame->flags & CAN_FRAME_IDE) != 0 ? 0 : 5, "",
frame->id_type == CAN_STANDARD_IDENTIFIER ? 3 : 8, (frame->flags & CAN_FRAME_IDE) != 0 ? 8 : 3,
frame->id_type == CAN_STANDARD_IDENTIFIER ? (frame->flags & CAN_FRAME_IDE) != 0 ?
frame->id & CAN_STD_ID_MASK : frame->id & CAN_EXT_ID_MASK); frame->id & CAN_EXT_ID_MASK : frame->id & CAN_STD_ID_MASK);
/* DLC as number of bytes */ /* DLC as number of bytes */
shell_fprintf(sh, SHELL_NORMAL, "%s[%0*d] ", shell_fprintf(sh, SHELL_NORMAL, "%s[%0*d] ",
frame->fd == 0 ? " " : "", (frame->flags & CAN_FRAME_FDF) != 0 ? "" : " ",
frame->fd == 0 ? 1 : 2, (frame->flags & CAN_FRAME_FDF) != 0 ? 2 : 1,
nbytes); nbytes);
/* Data payload */ /* 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++) { for (i = 0; i < nbytes; i++) {
shell_fprintf(sh, SHELL_NORMAL, "%02x ", frame->data[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"); 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; 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) { if (max_std_filters < 0 && max_std_filters != -ENOSYS) {
shell_error(sh, "failed to get maximum standard (11-bit) filters (err %d)", err); shell_error(sh, "failed to get maximum standard (11-bit) filters (err %d)", err);
return 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) { if (max_ext_filters < 0 && max_ext_filters != -ENOSYS) {
shell_error(sh, "failed to get maximum extended (29-bit) filters (err %d)", err); shell_error(sh, "failed to get maximum extended (29-bit) filters (err %d)", err);
return err; return err;
@ -524,11 +524,8 @@ static int cmd_can_send(const struct shell *sh, size_t argc, char **argv)
/* Defaults */ /* Defaults */
max_id = CAN_MAX_STD_ID; max_id = CAN_MAX_STD_ID;
frame.id_type = CAN_STANDARD_IDENTIFIER; frame.flags = 0;
frame.rtr = CAN_DATAFRAME;
frame.dlc = 0; frame.dlc = 0;
frame.fd = 0;
frame.brs = 0;
/* Parse options */ /* Parse options */
while (argidx < argc && strncmp(argv[argidx], "-", 1) == 0) { 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++; argidx++;
break; break;
} else if (strcmp(argv[argidx], "-e") == 0) { } else if (strcmp(argv[argidx], "-e") == 0) {
frame.id_type = CAN_EXTENDED_IDENTIFIER; frame.flags |= CAN_FRAME_IDE;
max_id = CAN_MAX_EXT_ID; max_id = CAN_MAX_EXT_ID;
argidx++; argidx++;
} else if (strcmp(argv[argidx], "-r") == 0) { } else if (strcmp(argv[argidx], "-r") == 0) {
frame.rtr = CAN_REMOTEREQUEST; frame.flags |= CAN_FRAME_RTR;
argidx++; argidx++;
} else if (strcmp(argv[argidx], "-f") == 0) { } else if (strcmp(argv[argidx], "-f") == 0) {
frame.fd = 1; frame.flags |= CAN_FRAME_FDF;
argidx++; argidx++;
} else if (strcmp(argv[argidx], "-b") == 0) { } else if (strcmp(argv[argidx], "-b") == 0) {
frame.brs = 1; frame.flags |= CAN_FRAME_BRS;
argidx++; argidx++;
} else { } else {
shell_error(sh, "unsupported option %s", argv[argidx]); 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) { if (val > max_id) {
shell_error(sh, "CAN ID 0x%0*x out of range", 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); val);
return -EINVAL; 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, " 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, "RTR %d, CAN-FD %d, BRS %d, DLC %d", frame_no,
frame.id_type == CAN_STANDARD_IDENTIFIER ? "standard" : "extended", (frame.flags & CAN_FRAME_IDE) != 0 ? "extended" : "standard",
frame.id_type == CAN_STANDARD_IDENTIFIER ? 11 : 29, (frame.flags & CAN_FRAME_IDE) != 0 ? 29 : 11,
frame.id_type == CAN_STANDARD_IDENTIFIER ? 3 : 8, frame.id, (frame.flags & CAN_FRAME_IDE) != 0 ? 8 : 3, frame.id,
frame.rtr, frame.fd, frame.brs, can_dlc_to_bytes(frame.dlc)); (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)); err = can_send(dev, &frame, K_NO_WAIT, can_shell_tx_callback, UINT_TO_POINTER(frame_no));
if (err != 0) { if (err != 0) {
@ -641,9 +641,7 @@ static int cmd_can_filter_add(const struct shell *sh, size_t argc, char **argv)
/* Defaults */ /* Defaults */
max_id = CAN_MAX_STD_ID; max_id = CAN_MAX_STD_ID;
filter.id_type = CAN_STANDARD_IDENTIFIER; filter.flags = CAN_FILTER_DATA;
filter.rtr = CAN_DATAFRAME;
filter.rtr_mask = 0;
/* Parse options */ /* Parse options */
while (argidx < argc && strncmp(argv[argidx], "-", 1) == 0) { 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++; argidx++;
break; break;
} else if (strcmp(argv[argidx], "-e") == 0) { } else if (strcmp(argv[argidx], "-e") == 0) {
filter.id_type = CAN_EXTENDED_IDENTIFIER; filter.flags |= CAN_FILTER_IDE;
max_id = CAN_MAX_EXT_ID; max_id = CAN_MAX_EXT_ID;
argidx++; argidx++;
} else if (strcmp(argv[argidx], "-r") == 0) { } else if (strcmp(argv[argidx], "-r") == 0) {
filter.rtr = CAN_REMOTEREQUEST; filter.flags |= CAN_FILTER_RTR;
argidx++; argidx++;
} else if (strcmp(argv[argidx], "-R") == 0) { } else if (strcmp(argv[argidx], "-R") == 0) {
filter.rtr_mask = 1; filter.flags &= ~(CAN_FILTER_DATA);
filter.flags |= CAN_FILTER_RTR;
argidx++; argidx++;
} else { } else {
shell_error(sh, "unsupported argument %s", argv[argidx]); 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) { if (val > max_id) {
shell_error(sh, "CAN ID 0x%0*x out of range", 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); val);
return -EINVAL; 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) { if (val > max_id) {
shell_error(sh, "CAN ID mask 0x%0*x out of range", 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); val);
return -EINVAL; return -EINVAL;
} }
@ -708,7 +707,7 @@ static int cmd_can_filter_add(const struct shell *sh, size_t argc, char **argv)
val = max_id; val = max_id;
} }
filter.id_mask = val; filter.mask = val;
err = can_shell_rx_msgq_poll_submit(sh); err = can_shell_rx_msgq_poll_submit(sh);
if (err != 0) { 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, " 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", "CAN ID mask 0x%0*x, data frames %d, RTR frames %d",
filter.id_type == CAN_STANDARD_IDENTIFIER ? "standard" : "extended", (filter.flags & CAN_FILTER_IDE) != 0 ? "extended" : "standard",
filter.id_type == CAN_STANDARD_IDENTIFIER ? 11 : 29, (filter.flags & CAN_FILTER_IDE) != 0 ? 29 : 11,
filter.id_type == CAN_STANDARD_IDENTIFIER ? 3 : 8, filter.id, (filter.flags & CAN_FILTER_IDE) != 0 ? 8 : 3, filter.id,
filter.id_type == CAN_STANDARD_IDENTIFIER ? 3 : 8, filter.id_mask, (filter.flags & CAN_FILTER_IDE) != 0 ? 8 : 3, filter.mask,
filter.rtr, filter.rtr_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); err = can_add_rx_filter_msgq(dev, &can_shell_rx_msgq, &filter);
if (err < 0) { if (err < 0) {
@ -841,8 +841,8 @@ SHELL_STATIC_SUBCMD_SET_CREATE(sub_can_filter_cmds,
"Add rx filter\n" "Add rx filter\n"
"Usage: can filter add <device> [-e] [-r] [-R] <CAN ID> [CAN ID mask]\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" "-e use extended (29-bit) CAN ID/CAN ID mask\n"
"-r set Remote Transmission Request (RTR) bit\n" "-r also match Remote Transmission Request (RTR) frames\n"
"-R set Remote Transmission Request (RTR) mask", "-R only match Remote Transmission Request (RTR) frames",
cmd_can_filter_add, 3, 4), cmd_can_filter_add, 3, 4),
SHELL_CMD_ARG(remove, &dsub_can_device_name, SHELL_CMD_ARG(remove, &dsub_can_device_name,
"Remove rx filter\n" "Remove rx filter\n"

View file

@ -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); info = can_sja1000_read_reg(dev, CAN_SJA1000_FRAME_INFO);
if ((info & CAN_SJA1000_FRAME_INFO_RTR) != 0) { if ((info & CAN_SJA1000_FRAME_INFO_RTR) != 0) {
frame->rtr = CAN_REMOTEREQUEST; frame->flags |= CAN_FRAME_RTR;
} else {
frame->rtr = CAN_DATAFRAME;
} }
frame->dlc = CAN_SJA1000_FRAME_INFO_DLC_GET(info); 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) { 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), frame->id = FIELD_PREP(GENMASK(28, 21),
can_sja1000_read_reg(dev, CAN_SJA1000_XFF_ID1)); 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); frame->data[i] = can_sja1000_read_reg(dev, CAN_SJA1000_EFF_DATA + i);
} }
} else { } else {
frame->id_type = CAN_STANDARD_IDENTIFIER;
frame->id = FIELD_PREP(GENMASK(10, 3), frame->id = FIELD_PREP(GENMASK(10, 3),
can_sja1000_read_reg(dev, CAN_SJA1000_XFF_ID1)); can_sja1000_read_reg(dev, CAN_SJA1000_XFF_ID1));
frame->id |= FIELD_PREP(GENMASK(2, 0), 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); 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; 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; info |= CAN_SJA1000_FRAME_INFO_FF;
} }
can_sja1000_write_reg(dev, CAN_SJA1000_FRAME_INFO, info); 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, can_sja1000_write_reg(dev, CAN_SJA1000_XFF_ID1,
FIELD_GET(GENMASK(28, 21), frame->id)); FIELD_GET(GENMASK(28, 21), frame->id));
can_sja1000_write_reg(dev, CAN_SJA1000_XFF_ID2, 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; 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) { if (!data->started) {
return -ENETDOWN; 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 filter_id = -ENOSPC;
int i; 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++) { for (i = 0; i < ARRAY_SIZE(data->filters); i++) {
if (!atomic_test_and_set_bit(data->rx_allocs, i)) { if (!atomic_test_and_set_bit(data->rx_allocs, i)) {
filter_id = 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; 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(dev);
ARG_UNUSED(id_type); ARG_UNUSED(ide);
return CONFIG_CAN_MAX_FILTER; return CONFIG_CAN_MAX_FILTER;
} }

View file

@ -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, void can_sja1000_set_state_change_callback(const struct device *dev,
can_state_change_callback_t callback, void *user_data); 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); int can_sja1000_get_max_bitrate(const struct device *dev, uint32_t *max_bitrate);

View file

@ -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) 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) { if (mbox->RIR & CAN_RI0R_IDE) {
frame->id = mbox->RIR >> CAN_RI0R_EXID_Pos; frame->id = mbox->RIR >> CAN_RI0R_EXID_Pos;
frame->id_type = CAN_EXTENDED_IDENTIFIER; frame->flags |= CAN_FRAME_IDE;
} else { } else {
frame->id = mbox->RIR >> CAN_RI0R_STID_Pos; frame->id = mbox->RIR >> CAN_RI0R_STID_Pos;
frame->id_type = CAN_STANDARD_IDENTIFIER; }
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->dlc = mbox->RDTR & (CAN_RDT0R_DLC >> CAN_RDT0R_DLC_Pos);
frame->data_32[0] = mbox->RDLR; frame->data_32[0] = mbox->RDLR;
frame->data_32[1] = mbox->RDHR; 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; 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); ARG_UNUSED(dev);
if (id_type == CAN_STANDARD_IDENTIFIER) { if (ide) {
return CONFIG_CAN_MAX_STD_ID_FILTER;
} else {
return CONFIG_CAN_MAX_EXT_ID_FILTER; 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" "Remote Frame: %s"
, frame->dlc, dev->name , frame->dlc, dev->name
, frame->id , frame->id
, frame->id_type == CAN_STANDARD_IDENTIFIER ? , (frame->flags & CAN_FRAME_IDE) != 0 ? "extended" : "standard"
"standard" : "extended" , (frame->flags & CAN_FRAME_RTR) != 0 ? "yes" : "no");
, frame->rtr == CAN_DATAFRAME ? "no" : "yes");
__ASSERT_NO_MSG(callback != NULL); __ASSERT_NO_MSG(callback != NULL);
__ASSERT(frame->dlc == 0U || frame->data != NULL, "Dataptr is 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; 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) { if (!data->started) {
return -ENETDOWN; 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 identifier register setup */
mailbox->TIR &= CAN_TI0R_TXRQ; mailbox->TIR &= CAN_TI0R_TXRQ;
if (frame->id_type == CAN_STANDARD_IDENTIFIER) { if ((frame->flags & CAN_FRAME_IDE) != 0) {
mailbox->TIR |= (frame->id << CAN_TI0R_STID_Pos);
} else {
mailbox->TIR |= (frame->id << CAN_TI0R_EXID_Pos) mailbox->TIR |= (frame->id << CAN_TI0R_EXID_Pos)
| CAN_TI0R_IDE; | 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; 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, 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) { if (ide) {
case CAN_STANDARD_IDENTIFIER: filter_reg->FR1 = id;
filter_reg->FR2 = mask;
} else {
if ((filter_id - CONFIG_CAN_MAX_EXT_ID_FILTER) % 2 == 0) { if ((filter_id - CONFIG_CAN_MAX_EXT_ID_FILTER) % 2 == 0) {
/* even std filter id: first 1/2 bank */ /* even std filter id: first 1/2 bank */
filter_reg->FR1 = id | (mask << 16); 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 */ /* uneven std filter id: first 1/2 bank */
filter_reg->FR2 = id | (mask << 16); 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) 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) | uint32_t rtr_mask = (filter->flags & (CAN_FILTER_DATA | CAN_FILTER_RTR)) !=
(filter->rtr_mask << CAN_STM32_FIRX_STD_RTR_POS) | (CAN_FILTER_DATA | CAN_FILTER_RTR) ? 1U : 0U;
(1U << CAN_STM32_FIRX_STD_IDE_POS);
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) 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) | uint32_t rtr_mask = (filter->flags & (CAN_FILTER_DATA | CAN_FILTER_RTR)) !=
(filter->rtr_mask << CAN_STM32_FIRX_EXT_RTR_POS) | (CAN_FILTER_DATA | CAN_FILTER_RTR) ? 1U : 0U;
(1U << CAN_STM32_FIRX_EXT_IDE_POS);
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) static inline uint32_t can_stm32_filter_to_std_id(const struct can_filter *filter)
{ {
return (filter->id << CAN_STM32_FIRX_STD_ID_POS) | 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) 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) | return (filter->id << CAN_STM32_FIRX_EXT_EXT_ID_POS) |
(filter->rtr << CAN_STM32_FIRX_EXT_RTR_POS) | (((filter->flags & CAN_FILTER_RTR) != 0) ?
(1U << CAN_STM32_FIRX_EXT_IDE_POS); (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) 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; bank_offset = CAN_STM32_NUM_FILTER_BANKS;
} }
if (filter->id_type == CAN_STANDARD_IDENTIFIER) { if ((filter->flags & CAN_FILTER_IDE) != 0) {
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 {
for (int i = 0; i < CONFIG_CAN_MAX_EXT_ID_FILTER; i++) { for (int i = 0; i < CONFIG_CAN_MAX_EXT_ID_FILTER; i++) {
if (data->rx_cb_ext[i] == NULL) { if (data->rx_cb_ext[i] == NULL) {
id = can_stm32_filter_to_ext_id(filter); 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; 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) { if (filter_id != -ENOSPC) {
LOG_DBG("Adding filter_id %d, CAN ID: 0x%x, mask: 0x%x", 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 */ /* set the filter init mode */
can->FMR |= CAN_FMR_FINIT; can->FMR |= CAN_FMR_FINIT;
can_stm32_set_filter_bank(filter_id, &can->sFilterRegister[bank_num], 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->FA1R |= 1U << bank_num;
can->FMR &= ~(CAN_FMR_FINIT); 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; struct can_stm32_data *data = dev->data;
int filter_id; 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(&filter_mutex, K_FOREVER);
k_mutex_lock(&data->inst_mutex, K_FOREVER); k_mutex_lock(&data->inst_mutex, K_FOREVER);
filter_id = can_stm32_set_filter(dev, filter); filter_id = can_stm32_set_filter(dev, filter);
if (filter_id >= 0) { if (filter_id >= 0) {
if (filter->id_type == CAN_STANDARD_IDENTIFIER) { if ((filter->flags & CAN_FILTER_IDE) != 0) {
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 {
data->rx_cb_ext[filter_id] = cb; data->rx_cb_ext[filter_id] = cb;
data->cb_arg_ext[filter_id] = cb_arg; 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; const struct can_stm32_config *cfg = dev->config;
struct can_stm32_data *data = dev->data; struct can_stm32_data *data = dev->data;
CAN_TypeDef *can = cfg->master_can; CAN_TypeDef *can = cfg->master_can;
enum can_ide filter_type; bool ide;
int bank_offset = 0; int bank_offset = 0;
int bank_num; int bank_num;
bool bank_unused; 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) { if (filter_id < CONFIG_CAN_MAX_EXT_ID_FILTER) {
filter_type = CAN_EXTENDED_IDENTIFIER; ide = true;
bank_num = bank_offset + filter_id; bank_num = bank_offset + filter_id;
data->rx_cb_ext[filter_id] = NULL; 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 { } else {
int filter_index = filter_id - CONFIG_CAN_MAX_EXT_ID_FILTER; 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 + bank_num = bank_offset + CONFIG_CAN_MAX_EXT_ID_FILTER +
(filter_id - CONFIG_CAN_MAX_EXT_ID_FILTER) / 2; (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->FMR |= CAN_FMR_FINIT;
can_stm32_set_filter_bank(filter_id, &can->sFilterRegister[bank_num], can_stm32_set_filter_bank(filter_id, &can->sFilterRegister[bank_num],
filter_type, 0, 0xFFFFFFFF); ide, 0, 0xFFFFFFFF);
if (bank_unused) { if (bank_unused) {
can->FA1R &= ~(1U << bank_num); can->FA1R &= ~(1U << bank_num);

View file

@ -21,15 +21,19 @@
static inline bool can_utils_filter_match(const struct can_frame *frame, static inline bool can_utils_filter_match(const struct can_frame *frame,
struct can_filter *filter) 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; 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; 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; return false;
} }

View file

@ -126,45 +126,39 @@ enum can_state {
}; };
/** /**
* @brief Defines if the CAN frame has a standard (11-bit) or extended (29-bit) * @name CAN frame flags
* CAN identifier * @anchor CAN_FRAME_FLAGS
*
* @{
*/ */
enum can_ide {
/** Standard (11-bit) CAN identifier. */
CAN_STANDARD_IDENTIFIER,
/** Extended (29-bit) CAN identifier. */
CAN_EXTENDED_IDENTIFIER
};
/** /** Frame uses extended (29-bit) CAN ID */
* @brief Defines if the CAN frame is a data frame or a Remote Transmission Request (RTR) frame #define CAN_FRAME_IDE BIT(0)
*/
enum can_rtr { /** Frame is a Remote Transmission Request (RTR) */
/** Data frame. */ #define CAN_FRAME_RTR BIT(1)
CAN_DATAFRAME,
/** Remote Transmission Request (RTR) frame. */ /** Frame uses CAN-FD format (FDF) */
CAN_REMOTEREQUEST #define CAN_FRAME_FDF BIT(2)
};
/** Frame uses CAN-FD Baud Rate Switch (BRS). Only valid in combination with ``CAN_FRAME_FDF``. */
#define CAN_FRAME_BRS BIT(3)
/** @} */
/** /**
* @brief CAN frame structure * @brief CAN frame structure
*/ */
struct can_frame { struct can_frame {
/** Standard (11-bit) or extended (29-bit) CAN identifier. */ /** Standard (11-bit) or extended (29-bit) CAN identifier. */
uint32_t id : 29; uint32_t id : 29;
/** Frame is in the CAN-FD frame format if set to true. */ /** @cond INTERNAL_HIDDEN */
uint32_t fd : 1; uint8_t res0 : 3; /* reserved/padding. */
/** Remote Transmission Request (RTR) flag. Use @a can_rtr enum for assignment. */ /** @endcond */
uint32_t rtr : 1;
/** CAN identifier type (standard or extended). Use @a can_ide enum for assignment. */
uint32_t id_type : 1;
/** Data Length Code (DLC) indicating data length in bytes. */ /** Data Length Code (DLC) indicating data length in bytes. */
uint8_t dlc; uint8_t dlc;
/** Baud Rate Switch (BRS). Only valid for CAN-FD. */ /** Flags. @see @ref CAN_FRAME_FLAGS. */
uint8_t brs : 1; uint8_t flags;
/** @cond INTERNAL_HIDDEN */
uint8_t res : 7; /* reserved/padding. */
/** @endcond */
#if defined(CONFIG_CAN_RX_TIMESTAMP) || defined(__DOXYGEN__) #if defined(CONFIG_CAN_RX_TIMESTAMP) || defined(__DOXYGEN__)
/** Captured value of the free-running timer in the CAN controller when /** Captured value of the free-running timer in the CAN controller when
* this frame was received. The timer is incremented every bit time and * this frame was received. The timer is incremented every bit time and
@ -176,8 +170,7 @@ struct can_frame {
uint16_t timestamp; uint16_t timestamp;
#else #else
/** @cond INTERNAL_HIDDEN */ /** @cond INTERNAL_HIDDEN */
uint8_t res0; /* reserved/padding. */ uint16_t res1; /* reserved/padding. */
uint8_t res1; /* reserved/padding. */
/** @endcond */ /** @endcond */
#endif #endif
/** The frame payload data. */ /** The frame payload data. */
@ -187,6 +180,24 @@ struct can_frame {
}; };
}; };
/**
* @name CAN filter flags
* @anchor CAN_FILTER_FLAGS
*
* @{
*/
/** Filter matches frames with extended (29-bit) CAN IDs */
#define CAN_FILTER_IDE BIT(0)
/** Filter matches Remote Transmission Request (RTR) frames */
#define CAN_FILTER_RTR BIT(1)
/** Filter matches data frames */
#define CAN_FILTER_DATA BIT(2)
/** @} */
/** /**
* @brief CAN filter structure * @brief CAN filter structure
*/ */
@ -194,27 +205,14 @@ struct can_filter {
/** CAN identifier to match. */ /** CAN identifier to match. */
uint32_t id : 29; uint32_t id : 29;
/** @cond INTERNAL_HIDDEN */ /** @cond INTERNAL_HIDDEN */
uint32_t res0 : 1; uint32_t res0 : 3;
/** @endcond */ /** @endcond */
/** Match data frame or Remote Transmission Request (RTR) frame. */
uint32_t rtr : 1;
/** Standard or extended CAN identifier. Use @a can_ide enum for assignment. */
uint32_t id_type : 1;
/** CAN identifier matching mask. If a bit in this mask is 0, the value /** CAN identifier matching mask. If a bit in this mask is 0, the value
* of the corresponding bit in the ``id`` field is ignored by the filter. * of the corresponding bit in the ``id`` field is ignored by the filter.
*/ */
uint32_t id_mask : 29; uint32_t mask : 29;
/** @cond INTERNAL_HIDDEN */ /** Flags. @see @ref CAN_FILTER_FLAGS. */
uint32_t res1 : 1; uint8_t flags : 3;
/** @endcond */
/** Data frame/Remote Transmission Request (RTR) bit matching mask. If
* this bit is 0, the value of the ``rtr`` field is ignored by the
* filter.
*/
uint32_t rtr_mask : 1;
/** @cond INTERNAL_HIDDEN */
uint32_t res2 : 1;
/** @endcond */
}; };
/** /**
@ -407,7 +405,7 @@ typedef int (*can_get_core_clock_t)(const struct device *dev, uint32_t *rate);
* @brief Optional callback API upon getting the maximum number of concurrent CAN RX filters * @brief Optional callback API upon getting the maximum number of concurrent CAN RX filters
* See @a can_get_max_filters() for argument description * See @a can_get_max_filters() for argument description
*/ */
typedef int (*can_get_max_filters_t)(const struct device *dev, enum can_ide id_type); typedef int (*can_get_max_filters_t)(const struct device *dev, bool ide);
/** /**
* @brief Optional callback API upon getting the maximum supported bitrate * @brief Optional callback API upon getting the maximum supported bitrate
@ -1091,6 +1089,7 @@ __syscall int can_set_bitrate(const struct device *dev, uint32_t bitrate);
* *
* @retval 0 if successful. * @retval 0 if successful.
* @retval -EINVAL if an invalid parameter was passed to the function. * @retval -EINVAL if an invalid parameter was passed to the function.
* @retval -ENOTSUP if an unsupported parameter was passed to the function.
* @retval -ENETDOWN if the CAN controller is in stopped state. * @retval -ENETDOWN if the CAN controller is in stopped state.
* @retval -ENETUNREACH if the CAN controller is in bus-off state. * @retval -ENETUNREACH if the CAN controller is in bus-off state.
* @retval -EBUSY if CAN bus arbitration was lost (only applicable if automatic * @retval -EBUSY if CAN bus arbitration was lost (only applicable if automatic
@ -1131,6 +1130,7 @@ __syscall int can_send(const struct device *dev, const struct can_frame *frame,
* *
* @retval filter_id on success. * @retval filter_id on success.
* @retval -ENOSPC if there are no free filters. * @retval -ENOSPC if there are no free filters.
* @retval -EINVAL if the requested filter type is invalid.
* @retval -ENOTSUP if the requested filter type is not supported. * @retval -ENOTSUP if the requested filter type is not supported.
*/ */
static inline int can_add_rx_filter(const struct device *dev, can_rx_callback_t callback, static inline int can_add_rx_filter(const struct device *dev, can_rx_callback_t callback,
@ -1138,6 +1138,10 @@ static inline int can_add_rx_filter(const struct device *dev, can_rx_callback_t
{ {
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;
if (filter == NULL || (filter->flags & (CAN_FILTER_DATA | CAN_FILTER_RTR)) == 0) {
return -EINVAL;
}
return api->add_rx_filter(dev, callback, user_data, filter); return api->add_rx_filter(dev, callback, user_data, filter);
} }
@ -1203,15 +1207,16 @@ static inline void z_impl_can_remove_rx_filter(const struct device *dev, int fil
* Get the maximum number of concurrent RX filters for the CAN controller. * Get the maximum number of concurrent RX filters for the CAN controller.
* *
* @param dev Pointer to the device structure for the driver instance. * @param dev Pointer to the device structure for the driver instance.
* @param id_type CAN identifier type (standard or extended). * @param ide Get the maximum standard (11-bit) CAN ID filters if false, or extended (29-bit) CAN ID
* filters if true.
* *
* @retval Positive number of maximum concurrent filters. * @retval Positive number of maximum concurrent filters.
* @retval -EIO General input/output error. * @retval -EIO General input/output error.
* @retval -ENOSYS If this function is not implemented by the driver. * @retval -ENOSYS If this function is not implemented by the driver.
*/ */
__syscall int can_get_max_filters(const struct device *dev, enum can_ide id_type); __syscall int can_get_max_filters(const struct device *dev, bool ide);
static inline int z_impl_can_get_max_filters(const struct device *dev, enum can_ide id_type) static inline int z_impl_can_get_max_filters(const struct device *dev, bool ide)
{ {
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;
@ -1219,7 +1224,7 @@ static inline int z_impl_can_get_max_filters(const struct device *dev, enum can_
return -ENOSYS; return -ENOSYS;
} }
return api->get_max_filters(dev, id_type); return api->get_max_filters(dev, ide);
} }
/** @} */ /** @} */

View file

@ -36,11 +36,14 @@ extern "C" {
static inline void socketcan_to_can_frame(const struct socketcan_frame *sframe, static inline void socketcan_to_can_frame(const struct socketcan_frame *sframe,
struct can_frame *zframe) struct can_frame *zframe)
{ {
zframe->id_type = (sframe->can_id & BIT(31)) >> 31; memset(zframe, 0, sizeof(*zframe));
zframe->rtr = (sframe->can_id & BIT(30)) >> 30;
zframe->flags |= (sframe->can_id & BIT(31)) != 0 ? CAN_FRAME_IDE : 0;
zframe->flags |= (sframe->can_id & BIT(30)) != 0 ? CAN_FRAME_RTR : 0;
zframe->flags |= (sframe->flags & CANFD_FDF) != 0 ? CAN_FRAME_FDF : 0;
zframe->flags |= (sframe->flags & CANFD_BRS) != 0 ? CAN_FRAME_BRS : 0;
zframe->id = sframe->can_id & BIT_MASK(29); zframe->id = sframe->can_id & BIT_MASK(29);
zframe->dlc = can_bytes_to_dlc(sframe->len); zframe->dlc = can_bytes_to_dlc(sframe->len);
zframe->fd = !!(sframe->flags & CANFD_FDF);
memcpy(zframe->data, sframe->data, MIN(sizeof(sframe->data), sizeof(zframe->data))); memcpy(zframe->data, sframe->data, MIN(sizeof(sframe->data), sizeof(zframe->data)));
} }
@ -53,11 +56,21 @@ static inline void socketcan_to_can_frame(const struct socketcan_frame *sframe,
static inline void socketcan_from_can_frame(const struct can_frame *zframe, static inline void socketcan_from_can_frame(const struct can_frame *zframe,
struct socketcan_frame *sframe) struct socketcan_frame *sframe)
{ {
sframe->can_id = (zframe->id_type << 31) | (zframe->rtr << 30) | zframe->id; memset(sframe, 0, sizeof(*sframe));
sframe->can_id = zframe->id;
sframe->can_id |= (zframe->flags & CAN_FRAME_IDE) != 0 ? BIT(31) : 0;
sframe->can_id |= (zframe->flags & CAN_FRAME_RTR) != 0 ? BIT(30) : 0;
sframe->len = can_dlc_to_bytes(zframe->dlc); sframe->len = can_dlc_to_bytes(zframe->dlc);
if (zframe->fd) {
sframe->flags = CANFD_FDF; if ((zframe->flags & CAN_FRAME_FDF) != 0) {
sframe->flags |= CANFD_FDF;
} }
if ((zframe->flags & CAN_FRAME_BRS) != 0) {
sframe->flags |= CANFD_BRS;
}
memcpy(sframe->data, zframe->data, MIN(sizeof(zframe->data), sizeof(sframe->data))); memcpy(sframe->data, zframe->data, MIN(sizeof(zframe->data), sizeof(sframe->data)));
} }
@ -70,11 +83,19 @@ static inline void socketcan_from_can_frame(const struct can_frame *zframe,
static inline void socketcan_to_can_filter(const struct socketcan_filter *sfilter, static inline void socketcan_to_can_filter(const struct socketcan_filter *sfilter,
struct can_filter *zfilter) struct can_filter *zfilter)
{ {
zfilter->id_type = (sfilter->can_id & BIT(31)) >> 31; memset(zfilter, 0, sizeof(*zfilter));
zfilter->rtr = (sfilter->can_id & BIT(30)) >> 30;
zfilter->flags |= (sfilter->can_id & BIT(31)) != 0 ? CAN_FILTER_IDE : 0;
zfilter->id = sfilter->can_id & BIT_MASK(29); zfilter->id = sfilter->can_id & BIT_MASK(29);
zfilter->rtr_mask = (sfilter->can_mask & BIT(30)) >> 30; zfilter->mask = sfilter->can_mask & BIT_MASK(29);
zfilter->id_mask = sfilter->can_mask & BIT_MASK(29);
if ((sfilter->can_mask & BIT(30)) == 0) {
zfilter->flags |= CAN_FILTER_DATA | CAN_FILTER_RTR;
} else if ((sfilter->can_id & BIT(30)) == 0) {
zfilter->flags |= CAN_FILTER_DATA;
} else {
zfilter->flags |= CAN_FILTER_RTR;
}
} }
/** /**
@ -86,10 +107,19 @@ static inline void socketcan_to_can_filter(const struct socketcan_filter *sfilte
static inline void socketcan_from_can_filter(const struct can_filter *zfilter, static inline void socketcan_from_can_filter(const struct can_filter *zfilter,
struct socketcan_filter *sfilter) struct socketcan_filter *sfilter)
{ {
sfilter->can_id = (zfilter->id_type << 31) | memset(sfilter, 0, sizeof(*sfilter));
(zfilter->rtr << 30) | zfilter->id;
sfilter->can_mask = (zfilter->rtr_mask << 30) | sfilter->can_id = zfilter->id;
(zfilter->id_type << 31) | zfilter->id_mask; sfilter->can_id |= (zfilter->flags & CAN_FILTER_IDE) != 0 ? BIT(31) : 0;
sfilter->can_id |= (zfilter->flags & CAN_FILTER_RTR) != 0 ? BIT(30) : 0;
sfilter->can_mask = zfilter->mask;
sfilter->can_mask |= (zfilter->flags & CAN_FILTER_IDE) != 0 ? BIT(31) : 0;
if ((zfilter->flags & (CAN_FILTER_DATA | CAN_FILTER_RTR)) !=
(CAN_FILTER_DATA | CAN_FILTER_RTR)) {
sfilter->can_mask |= BIT(30);
}
} }
/** /**

View file

@ -124,15 +124,16 @@ static void canopen_tx_retry(struct k_work *item)
int err; int err;
uint16_t i; uint16_t i;
memset(&frame, 0, sizeof(frame));
CO_LOCK_CAN_SEND(); CO_LOCK_CAN_SEND();
for (i = 0; i < CANmodule->tx_size; i++) { for (i = 0; i < CANmodule->tx_size; i++) {
buffer = &CANmodule->tx_array[i]; buffer = &CANmodule->tx_array[i];
if (buffer->bufferFull) { if (buffer->bufferFull) {
frame.id_type = CAN_STANDARD_IDENTIFIER;
frame.id = buffer->ident; frame.id = buffer->ident;
frame.dlc = buffer->DLC; frame.dlc = buffer->DLC;
frame.rtr = (buffer->rtr ? 1 : 0); frame.flags |= (buffer->rtr ? CAN_FRAME_RTR : 0);
memcpy(frame.data, buffer->data, buffer->DLC); memcpy(frame.data, buffer->data, buffer->DLC);
err = can_send(CANmodule->dev, &frame, K_NO_WAIT, err = can_send(CANmodule->dev, &frame, K_NO_WAIT,
@ -197,7 +198,7 @@ CO_ReturnError_t CO_CANmodule_init(CO_CANmodule_t *CANmodule,
return CO_ERROR_ILLEGAL_ARGUMENT; return CO_ERROR_ILLEGAL_ARGUMENT;
} }
max_filters = can_get_max_filters(ctx->dev, CAN_STANDARD_IDENTIFIER); max_filters = can_get_max_filters(ctx->dev, false);
if (max_filters != -ENOSYS) { if (max_filters != -ENOSYS) {
if (max_filters < 0) { if (max_filters < 0) {
LOG_ERR("unable to determine number of CAN RX filters"); LOG_ERR("unable to determine number of CAN RX filters");
@ -298,11 +299,9 @@ CO_ReturnError_t CO_CANrxBufferInit(CO_CANmodule_t *CANmodule, uint16_t index,
buffer->object = object; buffer->object = object;
buffer->pFunct = pFunct; buffer->pFunct = pFunct;
filter.id_type = CAN_STANDARD_IDENTIFIER; filter.flags = (rtr ? CAN_FILTER_RTR : CAN_FILTER_DATA);
filter.id = ident; filter.id = ident;
filter.id_mask = mask; filter.mask = mask;
filter.rtr = (rtr ? 1 : 0);
filter.rtr_mask = 1;
if (buffer->filter_id != -ENOSPC) { if (buffer->filter_id != -ENOSPC) {
can_remove_rx_filter(CANmodule->dev, buffer->filter_id); can_remove_rx_filter(CANmodule->dev, buffer->filter_id);
@ -358,6 +357,8 @@ CO_ReturnError_t CO_CANsend(CO_CANmodule_t *CANmodule, CO_CANtx_t *buffer)
return CO_ERROR_ILLEGAL_ARGUMENT; return CO_ERROR_ILLEGAL_ARGUMENT;
} }
memset(&frame, 0, sizeof(frame));
CO_LOCK_CAN_SEND(); CO_LOCK_CAN_SEND();
if (buffer->bufferFull) { if (buffer->bufferFull) {
@ -369,10 +370,9 @@ CO_ReturnError_t CO_CANsend(CO_CANmodule_t *CANmodule, CO_CANtx_t *buffer)
ret = CO_ERROR_TX_OVERFLOW; ret = CO_ERROR_TX_OVERFLOW;
} }
frame.id_type = CAN_STANDARD_IDENTIFIER;
frame.id = buffer->ident; frame.id = buffer->ident;
frame.dlc = buffer->DLC; frame.dlc = buffer->DLC;
frame.rtr = (buffer->rtr ? 1 : 0); frame.flags = (buffer->rtr ? CAN_FRAME_RTR : 0);
memcpy(frame.data, buffer->data, buffer->DLC); memcpy(frame.data, buffer->data, buffer->DLC);
err = can_send(CANmodule->dev, &frame, K_NO_WAIT, canopen_tx_callback, err = can_send(CANmodule->dev, &frame, K_NO_WAIT, canopen_tx_callback,

View file

@ -15,29 +15,6 @@
#define BUTTON_NODE DT_ALIAS(sw0) #define BUTTON_NODE DT_ALIAS(sw0)
#define BUTTON_NAME DT_PROP_OR(BUTTON_NODE, label, "sw0") #define BUTTON_NAME DT_PROP_OR(BUTTON_NODE, label, "sw0")
/* CAN frame to be sent */
static const struct can_frame frame = {
#ifdef CONFIG_SAMPLE_CAN_BABBLING_EXT_ID
.id_type = CAN_EXTENDED_IDENTIFIER,
#else /* CONFIG_SAMPLE_CAN_BABBLING_EXT_ID */
.id_type = CAN_STANDARD_IDENTIFIER,
#endif /* ! CONFIG_SAMPLE_CAN_BABBLING_EXT_ID */
.id = CONFIG_SAMPLE_CAN_BABBLING_CAN_ID,
#ifdef CONFIG_SAMPLE_CAN_BABBLING_RTR
.rtr = CAN_REMOTEREQUEST,
#else /* CONFIG_SAMPLE_CAN_BABBLING_RTR */
.rtr = CAN_DATAFRAME,
#endif /* !CONFIG_SAMPLE_CAN_BABBLING_RTR */
#ifdef CONFIG_SAMPLE_CAN_BABBLING_FD_MODE
.fd = 1,
#else /* CONFIG_SAMPLE_CAN_BABBLING_FD_MODE */
.fd = 0,
#endif /* !CONFIG_SAMPLE_CAN_BABBLING_FD_MODE */
.brs = 0,
.dlc = 0,
.data = { },
};
#if DT_NODE_EXISTS(BUTTON_NODE) #if DT_NODE_EXISTS(BUTTON_NODE)
struct button_callback_context { struct button_callback_context {
struct gpio_callback callback; struct gpio_callback callback;
@ -69,6 +46,7 @@ void main(void)
#endif /* DT_NODE_EXISTS(BUTTON_NODE) */ #endif /* DT_NODE_EXISTS(BUTTON_NODE) */
const struct device *dev = DEVICE_DT_GET(CANBUS_NODE); const struct device *dev = DEVICE_DT_GET(CANBUS_NODE);
struct k_sem tx_queue_sem; struct k_sem tx_queue_sem;
struct can_frame frame = {0};
int err; int err;
k_sem_init(&tx_queue_sem, CONFIG_SAMPLE_CAN_BABBLING_TX_QUEUE_SIZE, k_sem_init(&tx_queue_sem, CONFIG_SAMPLE_CAN_BABBLING_TX_QUEUE_SIZE,
@ -109,12 +87,27 @@ void main(void)
gpio_add_callback(btn.port, &btn_cb_ctx.callback); gpio_add_callback(btn.port, &btn_cb_ctx.callback);
#endif /* DT_NODE_EXISTS(BUTTON_NODE) */ #endif /* DT_NODE_EXISTS(BUTTON_NODE) */
if (IS_ENABLED(CONFIG_SAMPLE_CAN_BABBLING_EXT_ID)) {
frame.flags |= CAN_FRAME_IDE;
}
if (IS_ENABLED(CONFIG_SAMPLE_CAN_BABBLING_RTR)) {
frame.flags |= CAN_FRAME_RTR;
}
if (IS_ENABLED(CONFIG_SAMPLE_CAN_BABBLING_FD_MODE)) {
frame.flags |= CAN_FRAME_FDF;
}
frame.id = CONFIG_SAMPLE_CAN_BABBLING_CAN_ID;
printk("babbling on %s with %s (%d-bit) CAN ID 0x%0*x, RTR %d, CAN-FD %d\n", printk("babbling on %s with %s (%d-bit) CAN ID 0x%0*x, RTR %d, CAN-FD %d\n",
dev->name, dev->name,
frame.id_type == CAN_STANDARD_IDENTIFIER ? "standard" : "extended", (frame.flags & CAN_FRAME_IDE) != 0 ? "extended" : "standard",
frame.id_type == CAN_STANDARD_IDENTIFIER ? 11 : 29, (frame.flags & CAN_FRAME_IDE) != 0 ? 29 : 11,
frame.id_type == CAN_STANDARD_IDENTIFIER ? 3 : 8, frame.id, (frame.flags & CAN_FRAME_IDE) != 0 ? 8 : 3, frame.id,
frame.rtr, frame.fd); (frame.flags & CAN_FRAME_RTR) != 0 ? 1 : 0,
(frame.flags & CAN_FRAME_FDF) != 0 ? 1 : 0);
#if DT_NODE_EXISTS(BUTTON_NODE) #if DT_NODE_EXISTS(BUTTON_NODE)
printk("abort by pressing %s button\n", BUTTON_NAME); printk("abort by pressing %s button\n", BUTTON_NAME);

View file

@ -61,11 +61,9 @@ void rx_thread(void *arg1, void *arg2, void *arg3)
ARG_UNUSED(arg2); ARG_UNUSED(arg2);
ARG_UNUSED(arg3); ARG_UNUSED(arg3);
const struct can_filter filter = { const struct can_filter filter = {
.id_type = CAN_EXTENDED_IDENTIFIER, .flags = CAN_FILTER_DATA | CAN_FILTER_IDE,
.rtr = CAN_DATAFRAME,
.id = COUNTER_MSG_ID, .id = COUNTER_MSG_ID,
.rtr_mask = 1, .mask = CAN_EXT_ID_MASK
.id_mask = CAN_EXT_ID_MASK
}; };
struct can_frame frame; struct can_frame frame;
int filter_id; int filter_id;
@ -192,21 +190,17 @@ void state_change_callback(const struct device *dev, enum can_state state,
void main(void) void main(void)
{ {
const struct can_filter change_led_filter = { const struct can_filter change_led_filter = {
.id_type = CAN_STANDARD_IDENTIFIER, .flags = CAN_FILTER_DATA,
.rtr = CAN_DATAFRAME,
.id = LED_MSG_ID, .id = LED_MSG_ID,
.rtr_mask = 1, .mask = CAN_STD_ID_MASK
.id_mask = CAN_STD_ID_MASK
}; };
struct can_frame change_led_frame = { struct can_frame change_led_frame = {
.id_type = CAN_STANDARD_IDENTIFIER, .flags = 0,
.rtr = CAN_DATAFRAME,
.id = LED_MSG_ID, .id = LED_MSG_ID,
.dlc = 1 .dlc = 1
}; };
struct can_frame counter_frame = { struct can_frame counter_frame = {
.id_type = CAN_EXTENDED_IDENTIFIER, .flags = CAN_FRAME_IDE,
.rtr = CAN_DATAFRAME,
.id = COUNTER_MSG_ID, .id = COUNTER_MSG_ID,
.dlc = 2 .dlc = 2
}; };

View file

@ -13,7 +13,7 @@ tests:
type: multi_line type: multi_line
ordered: True ordered: True
regex: regex:
- "(.*)\\[0\\] CAN frame: type 0x0 RTR 0x0 EID 0x1 DLC 0x8" - "(.*)\\[0\\] CAN frame: IDE 0x0 RTR 0x0 ID 0x1 DLC 0x8"
- "(.*)f0 f1 f2 f3 f4 f5 f6 f7" - "(.*)f0 f1 f2 f3 f4 f5 f6 f7"
sample.net.sockets.can.two_sockets: sample.net.sockets.can.two_sockets:
extra_configs: extra_configs:
@ -22,7 +22,7 @@ tests:
type: multi_line type: multi_line
ordered: True ordered: True
regex: regex:
- "(.*)\\[0\\] CAN frame: type 0x0 RTR 0x0 EID 0x1 DLC 0x8" - "(.*)\\[0\\] CAN frame: IDE 0x0 RTR 0x0 ID 0x1 DLC 0x8"
- "(.*)f0 f1 f2 f3 f4 f5 f6 f7" - "(.*)f0 f1 f2 f3 f4 f5 f6 f7"
- "(.*)\\[1\\] CAN frame: type 0x0 RTR 0x0 EID 0x1 DLC 0x8" - "(.*)\\[1\\] CAN frame: IDE 0x0 RTR 0x0 ID 0x1 DLC 0x8"
- "(.*)f0 f1 f2 f3 f4 f5 f6 f7" - "(.*)f0 f1 f2 f3 f4 f5 f6 f7"

View file

@ -32,11 +32,9 @@ static struct k_thread rx_data;
#define CLOSE_PERIOD 15 #define CLOSE_PERIOD 15
static const struct can_filter zfilter = { static const struct can_filter zfilter = {
.id_type = CAN_STANDARD_IDENTIFIER, .flags = CAN_FILTER_DATA,
.rtr = CAN_DATAFRAME,
.id = 0x1, .id = 0x1,
.rtr_mask = 1, .mask = CAN_STD_ID_MASK
.id_mask = CAN_STD_ID_MASK
}; };
static struct socketcan_filter sfilter; static struct socketcan_filter sfilter;
@ -48,10 +46,8 @@ static void tx(int *can_fd)
struct socketcan_frame sframe = {0}; struct socketcan_frame sframe = {0};
int ret, i; int ret, i;
zframe.dlc = 8U;
zframe.id_type = CAN_STANDARD_IDENTIFIER;
zframe.id = 0x1; zframe.id = 0x1;
zframe.rtr = CAN_DATAFRAME; zframe.dlc = 8U;
for (i = 0; i < zframe.dlc; i++) { for (i = 0; i < zframe.dlc; i++) {
zframe.data[i] = 0xF0 | i; zframe.data[i] = 0xF0 | i;
@ -128,10 +124,15 @@ static void rx(int *can_fd, int *do_close_period,
socketcan_to_can_frame(&sframe, &zframe); socketcan_to_can_frame(&sframe, &zframe);
LOG_INF("[%d] CAN frame: type 0x%x RTR 0x%x EID 0x%x DLC 0x%x", LOG_INF("[%d] CAN frame: IDE 0x%x RTR 0x%x ID 0x%x DLC 0x%x",
fd, zframe.id_type, zframe.rtr, zframe.id, zframe.dlc); fd,
(zframe.flags & CAN_FRAME_IDE) != 0 ? 1 : 0,
(zframe.flags & CAN_FRAME_RTR) != 0 ? 1 : 0,
zframe.id, zframe.dlc);
if (!zframe.rtr) { if ((zframe.flags & CAN_FRAME_RTR) != 0) {
LOG_INF("[%d] EXT Remote frame received", fd);
} else {
if (zframe.dlc > 8) { if (zframe.dlc > 8) {
data = (uint8_t *)zframe.data_32; data = (uint8_t *)zframe.data_32;
} else { } else {
@ -139,8 +140,6 @@ static void rx(int *can_fd, int *do_close_period,
} }
LOG_HEXDUMP_INF(data, zframe.dlc, "Data"); LOG_HEXDUMP_INF(data, zframe.dlc, "Data");
} else {
LOG_INF("[%d] EXT Remote frame received", fd);
} }
if (POINTER_TO_INT(do_close_period) > 0) { if (POINTER_TO_INT(do_close_period) > 0) {

View file

@ -119,8 +119,7 @@ static inline uint32_t receive_get_sf_length(struct net_buf *buf)
static void receive_send_fc(struct isotp_recv_ctx *ctx, uint8_t fs) static void receive_send_fc(struct isotp_recv_ctx *ctx, uint8_t fs)
{ {
struct can_frame frame = { struct can_frame frame = {
.id_type = ctx->tx_addr.ide == 0 ? CAN_STANDARD_IDENTIFIER : CAN_EXTENDED_IDENTIFIER, .flags = ctx->tx_addr.ide != 0 ? CAN_FRAME_IDE : 0,
.rtr = CAN_DATAFRAME,
.id = ctx->tx_addr.ext_id .id = ctx->tx_addr.ext_id
}; };
uint8_t *data = frame.data; uint8_t *data = frame.data;
@ -571,11 +570,9 @@ static inline int attach_ff_filter(struct isotp_recv_ctx *ctx)
} }
struct can_filter filter = { struct can_filter filter = {
.id_type = ctx->rx_addr.ide == 0 ? CAN_STANDARD_IDENTIFIER : CAN_EXTENDED_IDENTIFIER, .flags = CAN_FILTER_DATA | ((ctx->rx_addr.ide != 0) ? CAN_FILTER_IDE : 0),
.rtr = CAN_DATAFRAME,
.id = ctx->rx_addr.ext_id, .id = ctx->rx_addr.ext_id,
.rtr_mask = 1, .mask = mask
.id_mask = mask
}; };
ctx->filter_id = can_add_rx_filter(ctx->can_dev, receive_can_rx, ctx, ctx->filter_id = can_add_rx_filter(ctx->can_dev, receive_can_rx, ctx,
@ -866,8 +863,7 @@ static void pull_data_ctx(struct isotp_send_ctx *ctx, size_t len)
static inline int send_sf(struct isotp_send_ctx *ctx) static inline int send_sf(struct isotp_send_ctx *ctx)
{ {
struct can_frame frame = { struct can_frame frame = {
.id_type = ctx->tx_addr.ide == 0 ? CAN_STANDARD_IDENTIFIER : CAN_EXTENDED_IDENTIFIER, .flags = ctx->tx_addr.ide != 0 ? CAN_FRAME_IDE : 0,
.rtr = CAN_DATAFRAME,
.id = ctx->tx_addr.ext_id .id = ctx->tx_addr.ext_id
}; };
size_t len = get_ctx_data_length(ctx); size_t len = get_ctx_data_length(ctx);
@ -904,8 +900,7 @@ static inline int send_sf(struct isotp_send_ctx *ctx)
static inline int send_ff(struct isotp_send_ctx *ctx) static inline int send_ff(struct isotp_send_ctx *ctx)
{ {
struct can_frame frame = { struct can_frame frame = {
.id_type = ctx->tx_addr.ide == 0 ? CAN_STANDARD_IDENTIFIER : CAN_EXTENDED_IDENTIFIER, .flags = ctx->tx_addr.ide != 0 ? CAN_FRAME_IDE : 0,
.rtr = CAN_DATAFRAME,
.id = ctx->tx_addr.ext_id, .id = ctx->tx_addr.ext_id,
.dlc = ISOTP_CAN_DL .dlc = ISOTP_CAN_DL
}; };
@ -946,8 +941,7 @@ static inline int send_ff(struct isotp_send_ctx *ctx)
static inline int send_cf(struct isotp_send_ctx *ctx) static inline int send_cf(struct isotp_send_ctx *ctx)
{ {
struct can_frame frame = { struct can_frame frame = {
.id_type = ctx->tx_addr.ide == 0 ? CAN_STANDARD_IDENTIFIER : CAN_EXTENDED_IDENTIFIER, .flags = ctx->tx_addr.ide != 0 ? CAN_FRAME_IDE : 0,
.rtr = CAN_DATAFRAME,
.id = ctx->tx_addr.ext_id, .id = ctx->tx_addr.ext_id,
}; };
int index = 0; int index = 0;
@ -1129,11 +1123,9 @@ static void send_work_handler(struct k_work *item)
static inline int attach_fc_filter(struct isotp_send_ctx *ctx) static inline int attach_fc_filter(struct isotp_send_ctx *ctx)
{ {
struct can_filter filter = { struct can_filter filter = {
.id_type = ctx->rx_addr.ide == 0 ? CAN_STANDARD_IDENTIFIER : CAN_EXTENDED_IDENTIFIER, .flags = CAN_FILTER_DATA | ((ctx->rx_addr.ide != 0) ? CAN_FILTER_IDE : 0),
.rtr = CAN_DATAFRAME,
.id = ctx->rx_addr.ext_id, .id = ctx->rx_addr.ext_id,
.rtr_mask = 1, .mask = CAN_EXT_ID_MASK
.id_mask = CAN_EXT_ID_MASK
}; };
ctx->filter_id = can_add_rx_filter(ctx->can_dev, send_can_rx_cb, ctx, ctx->filter_id = can_add_rx_filter(ctx->can_dev, send_can_rx_cb, ctx,

View file

@ -65,8 +65,7 @@ CAN_MSGQ_DEFINE(can_msgq, 5);
* @brief Standard (11-bit) CAN ID frame 1. * @brief Standard (11-bit) CAN ID frame 1.
*/ */
const struct can_frame test_std_frame_1 = { const struct can_frame test_std_frame_1 = {
.id_type = CAN_STANDARD_IDENTIFIER, .flags = 0,
.rtr = CAN_DATAFRAME,
.id = TEST_CAN_STD_ID_1, .id = TEST_CAN_STD_ID_1,
.dlc = 8, .dlc = 8,
.data = {1, 2, 3, 4, 5, 6, 7, 8} .data = {1, 2, 3, 4, 5, 6, 7, 8}
@ -76,8 +75,7 @@ const struct can_frame test_std_frame_1 = {
* @brief Standard (11-bit) CAN ID frame 2. * @brief Standard (11-bit) CAN ID frame 2.
*/ */
const struct can_frame test_std_frame_2 = { const struct can_frame test_std_frame_2 = {
.id_type = CAN_STANDARD_IDENTIFIER, .flags = 0,
.rtr = CAN_DATAFRAME,
.id = TEST_CAN_STD_ID_2, .id = TEST_CAN_STD_ID_2,
.dlc = 8, .dlc = 8,
.data = {1, 2, 3, 4, 5, 6, 7, 8} .data = {1, 2, 3, 4, 5, 6, 7, 8}
@ -87,8 +85,7 @@ const struct can_frame test_std_frame_2 = {
* @brief Extended (29-bit) CAN ID frame 1. * @brief Extended (29-bit) CAN ID frame 1.
*/ */
const struct can_frame test_ext_frame_1 = { const struct can_frame test_ext_frame_1 = {
.id_type = CAN_EXTENDED_IDENTIFIER, .flags = CAN_FRAME_IDE,
.rtr = CAN_DATAFRAME,
.id = TEST_CAN_EXT_ID_1, .id = TEST_CAN_EXT_ID_1,
.dlc = 8, .dlc = 8,
.data = {1, 2, 3, 4, 5, 6, 7, 8} .data = {1, 2, 3, 4, 5, 6, 7, 8}
@ -98,8 +95,7 @@ const struct can_frame test_ext_frame_1 = {
* @brief Extended (29-bit) CAN ID frame 1. * @brief Extended (29-bit) CAN ID frame 1.
*/ */
const struct can_frame test_ext_frame_2 = { const struct can_frame test_ext_frame_2 = {
.id_type = CAN_EXTENDED_IDENTIFIER, .flags = CAN_FRAME_IDE,
.rtr = CAN_DATAFRAME,
.id = TEST_CAN_EXT_ID_2, .id = TEST_CAN_EXT_ID_2,
.dlc = 8, .dlc = 8,
.data = {1, 2, 3, 4, 5, 6, 7, 8} .data = {1, 2, 3, 4, 5, 6, 7, 8}
@ -109,8 +105,7 @@ const struct can_frame test_ext_frame_2 = {
* @brief Standard (11-bit) CAN ID RTR frame 1. * @brief Standard (11-bit) CAN ID RTR frame 1.
*/ */
const struct can_frame test_std_rtr_frame_1 = { const struct can_frame test_std_rtr_frame_1 = {
.id_type = CAN_STANDARD_IDENTIFIER, .flags = CAN_FRAME_RTR,
.rtr = CAN_REMOTEREQUEST,
.id = TEST_CAN_STD_ID_1, .id = TEST_CAN_STD_ID_1,
.dlc = 0, .dlc = 0,
.data = {0} .data = {0}
@ -120,8 +115,7 @@ const struct can_frame test_std_rtr_frame_1 = {
* @brief Extended (29-bit) CAN ID RTR frame 1. * @brief Extended (29-bit) CAN ID RTR frame 1.
*/ */
const struct can_frame test_ext_rtr_frame_1 = { const struct can_frame test_ext_rtr_frame_1 = {
.id_type = CAN_EXTENDED_IDENTIFIER, .flags = CAN_FRAME_IDE | CAN_FILTER_RTR,
.rtr = CAN_REMOTEREQUEST,
.id = TEST_CAN_EXT_ID_1, .id = TEST_CAN_EXT_ID_1,
.dlc = 0, .dlc = 0,
.data = {0} .data = {0}
@ -132,11 +126,9 @@ const struct can_frame test_ext_rtr_frame_1 = {
* ``test_std_frame_1``. * ``test_std_frame_1``.
*/ */
const struct can_filter test_std_filter_1 = { const struct can_filter test_std_filter_1 = {
.id_type = CAN_STANDARD_IDENTIFIER, .flags = CAN_FILTER_DATA,
.rtr = CAN_DATAFRAME,
.id = TEST_CAN_STD_ID_1, .id = TEST_CAN_STD_ID_1,
.rtr_mask = 1, .mask = CAN_STD_ID_MASK
.id_mask = CAN_STD_ID_MASK
}; };
/** /**
@ -144,11 +136,9 @@ const struct can_filter test_std_filter_1 = {
* ``test_std_frame_2``. * ``test_std_frame_2``.
*/ */
const struct can_filter test_std_filter_2 = { const struct can_filter test_std_filter_2 = {
.id_type = CAN_STANDARD_IDENTIFIER, .flags = CAN_FILTER_DATA,
.rtr = CAN_DATAFRAME,
.id = TEST_CAN_STD_ID_2, .id = TEST_CAN_STD_ID_2,
.rtr_mask = 1, .mask = CAN_STD_ID_MASK
.id_mask = CAN_STD_ID_MASK
}; };
/** /**
@ -156,11 +146,9 @@ const struct can_filter test_std_filter_2 = {
* ``test_std_frame_1``. * ``test_std_frame_1``.
*/ */
const struct can_filter test_std_masked_filter_1 = { const struct can_filter test_std_masked_filter_1 = {
.id_type = CAN_STANDARD_IDENTIFIER, .flags = CAN_FILTER_DATA,
.rtr = CAN_DATAFRAME,
.id = TEST_CAN_STD_MASK_ID_1, .id = TEST_CAN_STD_MASK_ID_1,
.rtr_mask = 1, .mask = TEST_CAN_STD_MASK
.id_mask = TEST_CAN_STD_MASK
}; };
/** /**
@ -168,11 +156,9 @@ const struct can_filter test_std_masked_filter_1 = {
* ``test_std_frame_2``. * ``test_std_frame_2``.
*/ */
const struct can_filter test_std_masked_filter_2 = { const struct can_filter test_std_masked_filter_2 = {
.id_type = CAN_STANDARD_IDENTIFIER, .flags = CAN_FILTER_DATA,
.rtr = CAN_DATAFRAME,
.id = TEST_CAN_STD_MASK_ID_2, .id = TEST_CAN_STD_MASK_ID_2,
.rtr_mask = 1, .mask = TEST_CAN_STD_MASK
.id_mask = TEST_CAN_STD_MASK
}; };
/** /**
@ -180,11 +166,9 @@ const struct can_filter test_std_masked_filter_2 = {
* ``test_ext_frame_1``. * ``test_ext_frame_1``.
*/ */
const struct can_filter test_ext_filter_1 = { const struct can_filter test_ext_filter_1 = {
.id_type = CAN_EXTENDED_IDENTIFIER, .flags = CAN_FILTER_DATA | CAN_FILTER_IDE,
.rtr = CAN_DATAFRAME,
.id = TEST_CAN_EXT_ID_1, .id = TEST_CAN_EXT_ID_1,
.rtr_mask = 1, .mask = CAN_EXT_ID_MASK
.id_mask = CAN_EXT_ID_MASK
}; };
/** /**
@ -192,11 +176,9 @@ const struct can_filter test_ext_filter_1 = {
* ``test_ext_frame_2``. * ``test_ext_frame_2``.
*/ */
const struct can_filter test_ext_filter_2 = { const struct can_filter test_ext_filter_2 = {
.id_type = CAN_EXTENDED_IDENTIFIER, .flags = CAN_FILTER_DATA | CAN_FILTER_IDE,
.rtr = CAN_DATAFRAME,
.id = TEST_CAN_EXT_ID_2, .id = TEST_CAN_EXT_ID_2,
.rtr_mask = 1, .mask = CAN_EXT_ID_MASK
.id_mask = CAN_EXT_ID_MASK
}; };
/** /**
@ -204,11 +186,9 @@ const struct can_filter test_ext_filter_2 = {
* ``test_ext_frame_1``. * ``test_ext_frame_1``.
*/ */
const struct can_filter test_ext_masked_filter_1 = { const struct can_filter test_ext_masked_filter_1 = {
.id_type = CAN_EXTENDED_IDENTIFIER, .flags = CAN_FILTER_DATA | CAN_FILTER_IDE,
.rtr = CAN_DATAFRAME,
.id = TEST_CAN_EXT_MASK_ID_1, .id = TEST_CAN_EXT_MASK_ID_1,
.rtr_mask = 1, .mask = TEST_CAN_EXT_MASK
.id_mask = TEST_CAN_EXT_MASK
}; };
/** /**
@ -216,11 +196,9 @@ const struct can_filter test_ext_masked_filter_1 = {
* ``test_ext_frame_2``. * ``test_ext_frame_2``.
*/ */
const struct can_filter test_ext_masked_filter_2 = { const struct can_filter test_ext_masked_filter_2 = {
.id_type = CAN_EXTENDED_IDENTIFIER, .flags = CAN_FILTER_DATA | CAN_FILTER_IDE,
.rtr = CAN_DATAFRAME,
.id = TEST_CAN_EXT_ID_1, .id = TEST_CAN_EXT_ID_1,
.rtr_mask = 1, .mask = TEST_CAN_EXT_MASK
.id_mask = TEST_CAN_EXT_MASK
}; };
/** /**
@ -228,11 +206,9 @@ const struct can_filter test_ext_masked_filter_2 = {
* ``test_std_rtr_frame_1``. * ``test_std_rtr_frame_1``.
*/ */
const struct can_filter test_std_rtr_filter_1 = { const struct can_filter test_std_rtr_filter_1 = {
.id_type = CAN_STANDARD_IDENTIFIER, .flags = CAN_FILTER_RTR,
.rtr = CAN_REMOTEREQUEST,
.id = TEST_CAN_STD_ID_1, .id = TEST_CAN_STD_ID_1,
.rtr_mask = 1, .mask = CAN_STD_ID_MASK
.id_mask = CAN_STD_ID_MASK
}; };
/** /**
@ -240,11 +216,9 @@ const struct can_filter test_std_rtr_filter_1 = {
* ``test_ext_rtr_frame_1``. * ``test_ext_rtr_frame_1``.
*/ */
const struct can_filter test_ext_rtr_filter_1 = { const struct can_filter test_ext_rtr_filter_1 = {
.id_type = CAN_EXTENDED_IDENTIFIER, .flags = CAN_FILTER_RTR | CAN_FILTER_IDE,
.rtr = CAN_REMOTEREQUEST,
.id = TEST_CAN_EXT_ID_1, .id = TEST_CAN_EXT_ID_1,
.rtr_mask = 1, .mask = CAN_EXT_ID_MASK
.id_mask = CAN_EXT_ID_MASK
}; };
/** /**
@ -252,11 +226,9 @@ const struct can_filter test_ext_rtr_filter_1 = {
* ``TEST_CAN_SOME_STD_ID``. * ``TEST_CAN_SOME_STD_ID``.
*/ */
const struct can_filter test_std_some_filter = { const struct can_filter test_std_some_filter = {
.id_type = CAN_STANDARD_IDENTIFIER, .flags = CAN_FILTER_DATA,
.rtr = CAN_DATAFRAME,
.id = TEST_CAN_SOME_STD_ID, .id = TEST_CAN_SOME_STD_ID,
.rtr_mask = 1, .mask = CAN_STD_ID_MASK
.id_mask = CAN_STD_ID_MASK
}; };
/** /**
@ -270,8 +242,7 @@ static inline void assert_frame_equal(const struct can_frame *frame1,
const struct can_frame *frame2, const struct can_frame *frame2,
uint32_t id_mask) uint32_t id_mask)
{ {
zassert_equal(frame1->id_type, frame2->id_type, "ID type does not match"); zassert_equal(frame1->flags, frame2->flags, "Flags do not match");
zassert_equal(frame1->rtr, frame2->rtr, "RTR bit does not match");
zassert_equal(frame1->id | id_mask, frame2->id | id_mask, "ID does not match"); zassert_equal(frame1->id | id_mask, frame2->id | id_mask, "ID does not match");
zassert_equal(frame1->dlc, frame2->dlc, "DLC does not match"); zassert_equal(frame1->dlc, frame2->dlc, "DLC does not match");
zassert_mem_equal(frame1->data, frame2->data, frame1->dlc, "Received data differ"); zassert_mem_equal(frame1->data, frame2->data, frame1->dlc, "Received data differ");
@ -579,12 +550,12 @@ static void send_receive(const struct can_filter *filter1,
err = k_msgq_get(&can_msgq, &frame_buffer, TEST_RECEIVE_TIMEOUT); err = k_msgq_get(&can_msgq, &frame_buffer, TEST_RECEIVE_TIMEOUT);
zassert_equal(err, 0, "receive timeout"); zassert_equal(err, 0, "receive timeout");
if (filter1->id_type == CAN_STANDARD_IDENTIFIER) { if ((filter1->flags & CAN_FILTER_IDE) != 0) {
if (filter1->id_mask != CAN_STD_ID_MASK) { if (filter1->mask != CAN_EXT_ID_MASK) {
mask = 0x0F; mask = 0x0F;
} }
} else { } else {
if (filter1->id_mask != CAN_EXT_ID_MASK) { if (filter1->mask != CAN_STD_ID_MASK) {
mask = 0x0F; mask = 0x0F;
} }
} }
@ -594,20 +565,8 @@ static void send_receive(const struct can_filter *filter1,
k_sem_reset(&tx_callback_sem); k_sem_reset(&tx_callback_sem);
if (frame1->id_type == CAN_STANDARD_IDENTIFIER) { if ((frame1->flags & CAN_FRAME_IDE) != 0) {
if (filter1->id_mask == CAN_STD_ID_MASK) { if (filter1->mask == CAN_EXT_ID_MASK) {
filter_id_1 = add_rx_filter(can_dev, filter1, rx_std_callback_1);
filter_id_2 = add_rx_filter(can_dev, filter2, rx_std_callback_2);
send_test_frame_nowait(can_dev, frame1, tx_std_callback_1);
send_test_frame_nowait(can_dev, frame2, tx_std_callback_2);
} else {
filter_id_1 = add_rx_filter(can_dev, filter1, rx_std_mask_callback_1);
filter_id_2 = add_rx_filter(can_dev, filter2, rx_std_mask_callback_2);
send_test_frame_nowait(can_dev, frame1, tx_std_callback_1);
send_test_frame_nowait(can_dev, frame2, tx_std_callback_2);
}
} else {
if (filter1->id_mask == CAN_EXT_ID_MASK) {
filter_id_1 = add_rx_filter(can_dev, filter1, rx_ext_callback_1); filter_id_1 = add_rx_filter(can_dev, filter1, rx_ext_callback_1);
filter_id_2 = add_rx_filter(can_dev, filter2, rx_ext_callback_2); filter_id_2 = add_rx_filter(can_dev, filter2, rx_ext_callback_2);
send_test_frame_nowait(can_dev, frame1, tx_ext_callback_1); send_test_frame_nowait(can_dev, frame1, tx_ext_callback_1);
@ -618,6 +577,18 @@ static void send_receive(const struct can_filter *filter1,
send_test_frame_nowait(can_dev, frame1, tx_ext_callback_1); send_test_frame_nowait(can_dev, frame1, tx_ext_callback_1);
send_test_frame_nowait(can_dev, frame2, tx_ext_callback_2); send_test_frame_nowait(can_dev, frame2, tx_ext_callback_2);
} }
} else {
if (filter1->mask == CAN_STD_ID_MASK) {
filter_id_1 = add_rx_filter(can_dev, filter1, rx_std_callback_1);
filter_id_2 = add_rx_filter(can_dev, filter2, rx_std_callback_2);
send_test_frame_nowait(can_dev, frame1, tx_std_callback_1);
send_test_frame_nowait(can_dev, frame2, tx_std_callback_2);
} else {
filter_id_1 = add_rx_filter(can_dev, filter1, rx_std_mask_callback_1);
filter_id_2 = add_rx_filter(can_dev, filter2, rx_std_mask_callback_2);
send_test_frame_nowait(can_dev, frame1, tx_std_callback_1);
send_test_frame_nowait(can_dev, frame2, tx_std_callback_2);
}
} }
err = k_sem_take(&rx_callback_sem, TEST_RECEIVE_TIMEOUT); err = k_sem_take(&rx_callback_sem, TEST_RECEIVE_TIMEOUT);
@ -825,24 +796,23 @@ ZTEST(can_api, test_add_filter)
/** /**
* @brief Test adding up to and above the maximum number of RX filters. * @brief Test adding up to and above the maximum number of RX filters.
* *
* @param id_type CAN frame identifier type * @param ide standard (11-bit) CAN ID filters if false, or extended (29-bit) CAN ID filters if
* true.
* @param id_mask filter * @param id_mask filter
*/ */
static void add_remove_max_filters(enum can_ide id_type) static void add_remove_max_filters(bool ide)
{ {
uint32_t id_mask = id_type == CAN_STANDARD_IDENTIFIER ? CAN_STD_ID_MASK : CAN_EXT_ID_MASK; uint32_t id_mask = ide ? CAN_EXT_ID_MASK : CAN_STD_ID_MASK;
struct can_filter filter = { struct can_filter filter = {
.id_type = id_type, .flags = CAN_FILTER_DATA | (ide ? CAN_FILTER_IDE : 0),
.rtr = CAN_DATAFRAME,
.id = 0, .id = 0,
.rtr_mask = 1, .mask = id_mask,
.id_mask = id_mask,
}; };
int filter_id; int filter_id;
int max; int max;
int i; int i;
max = can_get_max_filters(can_dev, id_type); max = can_get_max_filters(can_dev, ide);
if (max == -ENOSYS || max == 0) { if (max == -ENOSYS || max == 0) {
/* /*
* Skip test if max is not known or no filters of the given type * Skip test if max is not known or no filters of the given type
@ -874,7 +844,7 @@ static void add_remove_max_filters(enum can_ide id_type)
*/ */
ZTEST_USER(can_api, test_max_std_filters) ZTEST_USER(can_api, test_max_std_filters)
{ {
add_remove_max_filters(CAN_STANDARD_IDENTIFIER); add_remove_max_filters(false);
} }
/** /**
@ -882,7 +852,7 @@ ZTEST_USER(can_api, test_max_std_filters)
*/ */
ZTEST_USER(can_api, test_max_ext_filters) ZTEST_USER(can_api, test_max_ext_filters)
{ {
add_remove_max_filters(CAN_EXTENDED_IDENTIFIER); add_remove_max_filters(true);
} }
/** /**
@ -1035,9 +1005,10 @@ ZTEST(can_api, test_send_receive_wrong_id)
*/ */
ZTEST_USER(can_api, test_send_invalid_dlc) ZTEST_USER(can_api, test_send_invalid_dlc)
{ {
struct can_frame frame; struct can_frame frame = {0};
int err; int err;
frame.id = TEST_CAN_STD_ID_1;
frame.dlc = CAN_MAX_DLC + 1; frame.dlc = CAN_MAX_DLC + 1;
err = can_send(can_dev, &frame, TEST_SEND_TIMEOUT, NULL, NULL); err = can_send(can_dev, &frame, TEST_SEND_TIMEOUT, NULL, NULL);

View file

@ -51,8 +51,7 @@ CAN_MSGQ_DEFINE(can_msgq, 5);
* @brief Standard (11-bit) CAN ID frame 1. * @brief Standard (11-bit) CAN ID frame 1.
*/ */
const struct can_frame test_std_frame_1 = { const struct can_frame test_std_frame_1 = {
.id_type = CAN_STANDARD_IDENTIFIER, .flags = 0,
.rtr = CAN_DATAFRAME,
.id = TEST_CAN_STD_ID_1, .id = TEST_CAN_STD_ID_1,
.dlc = 8, .dlc = 8,
.data = { 1, 2, 3, 4, 5, 6, 7, 8 } .data = { 1, 2, 3, 4, 5, 6, 7, 8 }
@ -62,8 +61,7 @@ const struct can_frame test_std_frame_1 = {
* @brief Standard (11-bit) CAN ID frame 2. * @brief Standard (11-bit) CAN ID frame 2.
*/ */
const struct can_frame test_std_frame_2 = { const struct can_frame test_std_frame_2 = {
.id_type = CAN_STANDARD_IDENTIFIER, .flags = 0,
.rtr = CAN_DATAFRAME,
.id = TEST_CAN_STD_ID_2, .id = TEST_CAN_STD_ID_2,
.dlc = 8, .dlc = 8,
.data = { 1, 2, 3, 4, 5, 6, 7, 8 } .data = { 1, 2, 3, 4, 5, 6, 7, 8 }
@ -73,12 +71,9 @@ const struct can_frame test_std_frame_2 = {
* @brief Standard (11-bit) CAN ID frame 1 with CAN-FD payload. * @brief Standard (11-bit) CAN ID frame 1 with CAN-FD payload.
*/ */
const struct can_frame test_std_frame_fd_1 = { const struct can_frame test_std_frame_fd_1 = {
.id = TEST_CAN_STD_ID_1, .flags = CAN_FRAME_FDF | CAN_FRAME_BRS,
.fd = 1, .id = TEST_CAN_STD_ID_1,
.rtr = CAN_DATAFRAME,
.id_type = CAN_STANDARD_IDENTIFIER,
.dlc = 0xf, .dlc = 0xf,
.brs = 1,
.data = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, .data = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45,
@ -90,12 +85,9 @@ const struct can_frame test_std_frame_fd_1 = {
* @brief Standard (11-bit) CAN ID frame 1 with CAN-FD payload. * @brief Standard (11-bit) CAN ID frame 1 with CAN-FD payload.
*/ */
const struct can_frame test_std_frame_fd_2 = { const struct can_frame test_std_frame_fd_2 = {
.id = TEST_CAN_STD_ID_2, .flags = CAN_FRAME_FDF | CAN_FRAME_BRS,
.fd = 1, .id = TEST_CAN_STD_ID_2,
.rtr = CAN_DATAFRAME,
.id_type = CAN_STANDARD_IDENTIFIER,
.dlc = 0xf, .dlc = 0xf,
.brs = 1,
.data = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, .data = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45,
@ -107,22 +99,18 @@ const struct can_frame test_std_frame_fd_2 = {
* @brief Standard (11-bit) CAN ID filter 1. * @brief Standard (11-bit) CAN ID filter 1.
*/ */
const struct can_filter test_std_filter_1 = { const struct can_filter test_std_filter_1 = {
.id_type = CAN_STANDARD_IDENTIFIER, .flags = CAN_FILTER_DATA,
.rtr = CAN_DATAFRAME,
.id = TEST_CAN_STD_ID_1, .id = TEST_CAN_STD_ID_1,
.rtr_mask = 1, .mask = CAN_STD_ID_MASK
.id_mask = CAN_STD_ID_MASK
}; };
/** /**
* @brief Standard (11-bit) CAN ID filter 2. * @brief Standard (11-bit) CAN ID filter 2.
*/ */
const struct can_filter test_std_filter_2 = { const struct can_filter test_std_filter_2 = {
.id_type = CAN_STANDARD_IDENTIFIER, .flags = CAN_FILTER_DATA,
.rtr = CAN_DATAFRAME,
.id = TEST_CAN_STD_ID_2, .id = TEST_CAN_STD_ID_2,
.rtr_mask = 1, .mask = CAN_STD_ID_MASK
.id_mask = CAN_STD_ID_MASK
}; };
/** /**
@ -134,9 +122,7 @@ const struct can_filter test_std_filter_2 = {
static inline void assert_frame_equal(const struct can_frame *frame1, static inline void assert_frame_equal(const struct can_frame *frame1,
const struct can_frame *frame2) const struct can_frame *frame2)
{ {
zassert_equal(frame1->id_type, frame2->id_type, "ID type does not match"); zassert_equal(frame1->flags, frame2->flags, "Flags do not match");
zassert_equal(frame1->fd, frame2->fd, "FD bit does not match");
zassert_equal(frame1->rtr, frame2->rtr, "RTR bit does not match");
zassert_equal(frame1->id, frame2->id, "ID does not match"); zassert_equal(frame1->id, frame2->id, "ID does not match");
zassert_equal(frame1->dlc, frame2->dlc, "DLC does not match"); zassert_equal(frame1->dlc, frame2->dlc, "DLC does not match");
zassert_mem_equal(frame1->data, frame2->data, frame1->dlc, "Received data differ"); zassert_mem_equal(frame1->data, frame2->data, frame1->dlc, "Received data differ");
@ -318,13 +304,13 @@ static void send_receive(const struct can_filter *filter1,
k_sem_reset(&tx_callback_sem); k_sem_reset(&tx_callback_sem);
if (frame1->fd) { if ((frame1->flags & CAN_FRAME_FDF) != 0) {
filter_id_1 = add_rx_filter(can_dev, filter1, rx_std_callback_fd_1); filter_id_1 = add_rx_filter(can_dev, filter1, rx_std_callback_fd_1);
} else { } else {
filter_id_1 = add_rx_filter(can_dev, filter1, rx_std_callback_1); filter_id_1 = add_rx_filter(can_dev, filter1, rx_std_callback_1);
} }
if (frame2->fd) { if ((frame2->flags & CAN_FRAME_FDF) != 0) {
filter_id_2 = add_rx_filter(can_dev, filter2, rx_std_callback_fd_2); filter_id_2 = add_rx_filter(can_dev, filter2, rx_std_callback_fd_2);
} else { } else {
filter_id_2 = add_rx_filter(can_dev, filter2, rx_std_callback_2); filter_id_2 = add_rx_filter(can_dev, filter2, rx_std_callback_2);

View file

@ -45,7 +45,7 @@ DEFINE_FAKE_VALUE_FUNC(int, fake_can_get_state, const struct device *, enum can_
DEFINE_FAKE_VOID_FUNC(fake_can_set_state_change_callback, const struct device *, DEFINE_FAKE_VOID_FUNC(fake_can_set_state_change_callback, const struct device *,
can_state_change_callback_t, void *); can_state_change_callback_t, void *);
DEFINE_FAKE_VALUE_FUNC(int, fake_can_get_max_filters, const struct device *, enum can_ide); DEFINE_FAKE_VALUE_FUNC(int, fake_can_get_max_filters, const struct device *, bool);
#ifdef CONFIG_ZTEST_NEW_API #ifdef CONFIG_ZTEST_NEW_API
static void fake_can_reset_rule_before(const struct ztest_unit_test *test, void *fixture) static void fake_can_reset_rule_before(const struct ztest_unit_test *test, void *fixture)

View file

@ -43,7 +43,7 @@ DECLARE_FAKE_VALUE_FUNC(int, fake_can_get_state, const struct device *, enum can
DECLARE_FAKE_VOID_FUNC(fake_can_set_state_change_callback, const struct device *, DECLARE_FAKE_VOID_FUNC(fake_can_set_state_change_callback, const struct device *,
can_state_change_callback_t, void *); can_state_change_callback_t, void *);
DECLARE_FAKE_VALUE_FUNC(int, fake_can_get_max_filters, const struct device *, enum can_ide); DECLARE_FAKE_VALUE_FUNC(int, fake_can_get_max_filters, const struct device *, bool);
#ifdef __cplusplus #ifdef __cplusplus
} }

View file

@ -41,20 +41,15 @@ static void assert_can_timing_equal(const struct can_timing *t1, const struct ca
static void assert_can_filter_equal(const struct can_filter *f1, const struct can_filter *f2) static void assert_can_filter_equal(const struct can_filter *f1, const struct can_filter *f2)
{ {
zassert_equal(f1->id_type, f2->id_type, "id_type mismatch"); zassert_equal(f1->flags, f2->flags, "flags mismatch");
zassert_equal(f1->id, f2->id, "id mismatch"); zassert_equal(f1->id, f2->id, "id mismatch");
zassert_equal(f1->id_mask, f2->id_mask, "id_mask mismatch"); zassert_equal(f1->mask, f2->mask, "mask mismatch");
zassert_equal(f1->rtr, f2->rtr, "rtr mismatch");
zassert_equal(f1->rtr_mask, f2->rtr_mask, "rtr_mask mismatch");
} }
static void assert_can_frame_equal(const struct can_frame *f1, const struct can_frame *f2) static void assert_can_frame_equal(const struct can_frame *f1, const struct can_frame *f2)
{ {
zassert_equal(f1->id_type, f2->id_type, "id_type mismatch"); zassert_equal(f1->flags, f2->flags, "flags mismatch");
zassert_equal(f1->id, f2->id, "id mismatch"); zassert_equal(f1->id, f2->id, "id mismatch");
zassert_equal(f1->rtr, f2->rtr, "rtr mismatch");
zassert_equal(f1->fd, f2->fd, "fd mismatch");
zassert_equal(f1->brs, f2->brs, "brs mismatch");
zassert_equal(f1->dlc, f2->dlc, "dlc mismatch"); zassert_equal(f1->dlc, f2->dlc, "dlc mismatch");
zassert_mem_equal(f1->data, f2->data, can_dlc_to_bytes(f1->dlc), "data mismatch"); zassert_mem_equal(f1->data, f2->data, can_dlc_to_bytes(f1->dlc), "data mismatch");
} }
@ -318,11 +313,8 @@ static void can_shell_test_send(const char *cmd, const struct can_frame *expecte
ZTEST(can_shell, test_can_send_std_id) ZTEST(can_shell, test_can_send_std_id)
{ {
const struct can_frame expected = { const struct can_frame expected = {
.id_type = CAN_STANDARD_IDENTIFIER, .flags = 0,
.id = 0x010, .id = 0x010,
.rtr = CAN_DATAFRAME,
.fd = 0,
.brs = 0,
.dlc = can_bytes_to_dlc(2), .dlc = can_bytes_to_dlc(2),
.data = { 0xaa, 0x55 }, .data = { 0xaa, 0x55 },
}; };
@ -333,11 +325,8 @@ ZTEST(can_shell, test_can_send_std_id)
ZTEST(can_shell, test_can_send_ext_id) ZTEST(can_shell, test_can_send_ext_id)
{ {
const struct can_frame expected = { const struct can_frame expected = {
.id_type = CAN_EXTENDED_IDENTIFIER, .flags = CAN_FRAME_IDE,
.id = 0x1024, .id = 0x1024,
.rtr = CAN_DATAFRAME,
.fd = 0,
.brs = 0,
.dlc = can_bytes_to_dlc(4), .dlc = can_bytes_to_dlc(4),
.data = { 0xde, 0xad, 0xbe, 0xef }, .data = { 0xde, 0xad, 0xbe, 0xef },
}; };
@ -348,11 +337,8 @@ ZTEST(can_shell, test_can_send_ext_id)
ZTEST(can_shell, test_can_send_no_data) ZTEST(can_shell, test_can_send_no_data)
{ {
const struct can_frame expected = { const struct can_frame expected = {
.id_type = CAN_STANDARD_IDENTIFIER, .flags = 0,
.id = 0x133, .id = 0x133,
.rtr = CAN_DATAFRAME,
.fd = 0,
.brs = 0,
.dlc = can_bytes_to_dlc(0), .dlc = can_bytes_to_dlc(0),
.data = { }, .data = { },
}; };
@ -363,11 +349,8 @@ ZTEST(can_shell, test_can_send_no_data)
ZTEST(can_shell, test_can_send_rtr) ZTEST(can_shell, test_can_send_rtr)
{ {
const struct can_frame expected = { const struct can_frame expected = {
.id_type = CAN_STANDARD_IDENTIFIER, .flags = CAN_FRAME_RTR,
.id = 0x7ff, .id = 0x7ff,
.rtr = CAN_REMOTEREQUEST,
.fd = 0,
.brs = 0,
.dlc = can_bytes_to_dlc(0), .dlc = can_bytes_to_dlc(0),
.data = { }, .data = { },
}; };
@ -378,11 +361,8 @@ ZTEST(can_shell, test_can_send_rtr)
ZTEST(can_shell, test_can_send_fd) ZTEST(can_shell, test_can_send_fd)
{ {
const struct can_frame expected = { const struct can_frame expected = {
.id_type = CAN_STANDARD_IDENTIFIER, .flags = CAN_FRAME_FDF,
.id = 0x123, .id = 0x123,
.rtr = CAN_DATAFRAME,
.fd = 1,
.brs = 0,
.dlc = can_bytes_to_dlc(8), .dlc = can_bytes_to_dlc(8),
.data = { 0xaa, 0x55, 0xaa, 0x55, 0x11, 0x22, 0x33, 0x44 }, .data = { 0xaa, 0x55, 0xaa, 0x55, 0x11, 0x22, 0x33, 0x44 },
}; };
@ -393,11 +373,8 @@ ZTEST(can_shell, test_can_send_fd)
ZTEST(can_shell, test_can_send_fd_brs) ZTEST(can_shell, test_can_send_fd_brs)
{ {
const struct can_frame expected = { const struct can_frame expected = {
.id_type = CAN_STANDARD_IDENTIFIER, .flags = CAN_FRAME_FDF | CAN_FRAME_BRS,
.id = 0x321, .id = 0x321,
.rtr = CAN_DATAFRAME,
.fd = 1,
.brs = 1,
.dlc = can_bytes_to_dlc(7), .dlc = can_bytes_to_dlc(7),
.data = { 0xaa, 0x55, 0xaa, 0x55, 0x11, 0x22, 0x33 }, .data = { 0xaa, 0x55, 0xaa, 0x55, 0x11, 0x22, 0x33 },
}; };
@ -408,11 +385,8 @@ ZTEST(can_shell, test_can_send_fd_brs)
ZTEST(can_shell, test_can_send_data_all_options) ZTEST(can_shell, test_can_send_data_all_options)
{ {
const struct can_frame expected = { const struct can_frame expected = {
.id_type = CAN_EXTENDED_IDENTIFIER, .flags = CAN_FRAME_IDE | CAN_FRAME_FDF | CAN_FRAME_BRS | CAN_FRAME_RTR,
.id = 0x1024, .id = 0x1024,
.rtr = CAN_REMOTEREQUEST,
.fd = 1,
.brs = 1,
.dlc = can_bytes_to_dlc(0), .dlc = can_bytes_to_dlc(0),
.data = { }, .data = { },
}; };
@ -449,11 +423,9 @@ static void can_shell_test_filter_add(const char *cmd, const struct can_filter *
ZTEST(can_shell, test_can_filter_add_std_id) ZTEST(can_shell, test_can_filter_add_std_id)
{ {
struct can_filter expected = { struct can_filter expected = {
.id_type = CAN_STANDARD_IDENTIFIER, .flags = CAN_FILTER_DATA,
.id = 0x010, .id = 0x010,
.id_mask = CAN_STD_ID_MASK, .mask = CAN_STD_ID_MASK,
.rtr = CAN_DATAFRAME,
.rtr_mask = 0,
}; };
can_shell_test_filter_add("can filter add " FAKE_CAN_NAME " 010", &expected); can_shell_test_filter_add("can filter add " FAKE_CAN_NAME " 010", &expected);
@ -462,11 +434,9 @@ ZTEST(can_shell, test_can_filter_add_std_id)
ZTEST(can_shell, test_can_filter_add_std_id_mask) ZTEST(can_shell, test_can_filter_add_std_id_mask)
{ {
struct can_filter expected = { struct can_filter expected = {
.id_type = CAN_STANDARD_IDENTIFIER, .flags = CAN_FILTER_DATA,
.id = 0x010, .id = 0x010,
.id_mask = 0x020, .mask = 0x020,
.rtr = CAN_DATAFRAME,
.rtr_mask = 0,
}; };
can_shell_test_filter_add("can filter add " FAKE_CAN_NAME " 010 020", &expected); can_shell_test_filter_add("can filter add " FAKE_CAN_NAME " 010 020", &expected);
@ -475,11 +445,9 @@ ZTEST(can_shell, test_can_filter_add_std_id_mask)
ZTEST(can_shell, test_can_filter_add_ext_id) ZTEST(can_shell, test_can_filter_add_ext_id)
{ {
struct can_filter expected = { struct can_filter expected = {
.id_type = CAN_EXTENDED_IDENTIFIER, .flags = CAN_FILTER_DATA | CAN_FILTER_IDE,
.id = 0x1024, .id = 0x1024,
.id_mask = CAN_EXT_ID_MASK, .mask = CAN_EXT_ID_MASK,
.rtr = CAN_DATAFRAME,
.rtr_mask = 0,
}; };
can_shell_test_filter_add("can filter add " FAKE_CAN_NAME " -e 1024", &expected); can_shell_test_filter_add("can filter add " FAKE_CAN_NAME " -e 1024", &expected);
@ -488,11 +456,9 @@ ZTEST(can_shell, test_can_filter_add_ext_id)
ZTEST(can_shell, test_can_filter_add_ext_id_mask) ZTEST(can_shell, test_can_filter_add_ext_id_mask)
{ {
struct can_filter expected = { struct can_filter expected = {
.id_type = CAN_EXTENDED_IDENTIFIER, .flags = CAN_FILTER_DATA | CAN_FILTER_IDE,
.id = 0x1024, .id = 0x1024,
.id_mask = 0x2048, .mask = 0x2048,
.rtr = CAN_DATAFRAME,
.rtr_mask = 0,
}; };
can_shell_test_filter_add("can filter add " FAKE_CAN_NAME " -e 1024 2048", &expected); can_shell_test_filter_add("can filter add " FAKE_CAN_NAME " -e 1024 2048", &expected);
@ -501,24 +467,20 @@ ZTEST(can_shell, test_can_filter_add_ext_id_mask)
ZTEST(can_shell, test_can_filter_add_rtr) ZTEST(can_shell, test_can_filter_add_rtr)
{ {
struct can_filter expected = { struct can_filter expected = {
.id_type = CAN_STANDARD_IDENTIFIER, .flags = CAN_FILTER_DATA | CAN_FILTER_RTR,
.id = 0x022, .id = 0x022,
.id_mask = CAN_STD_ID_MASK, .mask = CAN_STD_ID_MASK,
.rtr = CAN_REMOTEREQUEST,
.rtr_mask = 0,
}; };
can_shell_test_filter_add("can filter add " FAKE_CAN_NAME " -r 022", &expected); can_shell_test_filter_add("can filter add " FAKE_CAN_NAME " -r 022", &expected);
} }
ZTEST(can_shell, test_can_filter_add_rtr_mask) ZTEST(can_shell, test_can_filter_add_rtr_only)
{ {
struct can_filter expected = { struct can_filter expected = {
.id_type = CAN_STANDARD_IDENTIFIER, .flags = CAN_FILTER_RTR,
.id = 0x322, .id = 0x322,
.id_mask = CAN_STD_ID_MASK, .mask = CAN_STD_ID_MASK,
.rtr = CAN_DATAFRAME,
.rtr_mask = 1,
}; };
can_shell_test_filter_add("can filter add " FAKE_CAN_NAME " -R 322", &expected); can_shell_test_filter_add("can filter add " FAKE_CAN_NAME " -R 322", &expected);
@ -527,11 +489,9 @@ ZTEST(can_shell, test_can_filter_add_rtr_mask)
ZTEST(can_shell, test_can_filter_add_all_options) ZTEST(can_shell, test_can_filter_add_all_options)
{ {
struct can_filter expected = { struct can_filter expected = {
.id_type = CAN_EXTENDED_IDENTIFIER, .flags = CAN_FILTER_RTR | CAN_FILTER_IDE,
.id = 0x2048, .id = 0x2048,
.id_mask = 0x4096, .mask = 0x4096,
.rtr = CAN_REMOTEREQUEST,
.rtr_mask = 1,
}; };
can_shell_test_filter_add("can filter add " FAKE_CAN_NAME " -e -r -R 2048 4096", &expected); can_shell_test_filter_add("can filter add " FAKE_CAN_NAME " -e -r -R 2048 4096", &expected);

View file

@ -27,8 +27,7 @@ ZTEST(socket_can, test_socketcan_frame_to_can_frame)
sframe.len = sizeof(data); sframe.len = sizeof(data);
memcpy(sframe.data, data, sizeof(sframe.data)); memcpy(sframe.data, data, sizeof(sframe.data));
expected.rtr = CAN_REMOTEREQUEST; expected.flags = CAN_FRAME_IDE | CAN_FRAME_RTR;
expected.id_type = CAN_EXTENDED_IDENTIFIER;
expected.id = 1234U; expected.id = 1234U;
expected.dlc = sizeof(data); expected.dlc = sizeof(data);
@ -38,8 +37,7 @@ ZTEST(socket_can, test_socketcan_frame_to_can_frame)
LOG_HEXDUMP_DBG((const uint8_t *)&zframe, sizeof(zframe), "zframe"); LOG_HEXDUMP_DBG((const uint8_t *)&zframe, sizeof(zframe), "zframe");
LOG_HEXDUMP_DBG((const uint8_t *)&expected, sizeof(expected), "expected"); LOG_HEXDUMP_DBG((const uint8_t *)&expected, sizeof(expected), "expected");
zassert_equal(zframe.rtr, expected.rtr, "RTR bit not set"); zassert_equal(zframe.flags, expected.flags, "Flags not equal");
zassert_equal(zframe.id_type, expected.id_type, "Id-type bit not set");
zassert_equal(zframe.id, expected.id, "CAN id invalid"); zassert_equal(zframe.id, expected.id, "CAN id invalid");
zassert_equal(zframe.dlc, expected.dlc, "Msg length invalid"); zassert_equal(zframe.dlc, expected.dlc, "Msg length invalid");
} }
@ -59,8 +57,7 @@ ZTEST(socket_can, test_can_frame_to_socketcan_frame)
expected.len = sizeof(data); expected.len = sizeof(data);
memcpy(expected.data, data, sizeof(expected.data)); memcpy(expected.data, data, sizeof(expected.data));
zframe.rtr = CAN_REMOTEREQUEST; zframe.flags = CAN_FRAME_IDE | CAN_FRAME_RTR;
zframe.id_type = CAN_EXTENDED_IDENTIFIER;
zframe.id = 1234U; zframe.id = 1234U;
zframe.dlc = sizeof(data); zframe.dlc = sizeof(data);
memcpy(zframe.data, data, sizeof(data)); memcpy(zframe.data, data, sizeof(data));
@ -90,11 +87,9 @@ ZTEST(socket_can, test_socketcan_filter_to_can_filter)
sfilter.can_id = BIT(31) | BIT(30) | 1234; sfilter.can_id = BIT(31) | BIT(30) | 1234;
sfilter.can_mask = BIT(31) | BIT(30) | 1234; sfilter.can_mask = BIT(31) | BIT(30) | 1234;
expected.rtr = CAN_REMOTEREQUEST; expected.flags = CAN_FILTER_IDE | CAN_FILTER_RTR;
expected.id_type = CAN_EXTENDED_IDENTIFIER;
expected.id = 1234U; expected.id = 1234U;
expected.rtr_mask = 1U; expected.mask = 1234U;
expected.id_mask = 1234U;
socketcan_to_can_filter(&sfilter, &zfilter); socketcan_to_can_filter(&sfilter, &zfilter);
@ -102,11 +97,9 @@ ZTEST(socket_can, test_socketcan_filter_to_can_filter)
LOG_HEXDUMP_DBG((const uint8_t *)&sfilter, sizeof(sfilter), "sfilter"); LOG_HEXDUMP_DBG((const uint8_t *)&sfilter, sizeof(sfilter), "sfilter");
LOG_HEXDUMP_DBG((const uint8_t *)&expected, sizeof(expected), "expected"); LOG_HEXDUMP_DBG((const uint8_t *)&expected, sizeof(expected), "expected");
zassert_equal(zfilter.rtr, expected.rtr, "RTR bit not set"); zassert_equal(zfilter.flags, expected.flags, "Flags not equal");
zassert_equal(zfilter.id_type, expected.id_type, "Id-type bit not set");
zassert_equal(zfilter.id, expected.id, "CAN id invalid"); zassert_equal(zfilter.id, expected.id, "CAN id invalid");
zassert_equal(zfilter.rtr_mask, expected.rtr_mask, "RTR mask bit not set"); zassert_equal(zfilter.mask, expected.mask, "id mask not set");
zassert_equal(zfilter.id_mask, expected.id_mask, "id mask not set");
} }
/** /**
@ -121,11 +114,9 @@ ZTEST(socket_can, test_can_filter_to_socketcan_filter)
expected.can_id = BIT(31) | BIT(30) | 1234; expected.can_id = BIT(31) | BIT(30) | 1234;
expected.can_mask = BIT(31) | BIT(30) | 1234; expected.can_mask = BIT(31) | BIT(30) | 1234;
zfilter.rtr = CAN_REMOTEREQUEST; zfilter.flags = CAN_FILTER_IDE | CAN_FILTER_RTR;
zfilter.id_type = CAN_EXTENDED_IDENTIFIER;
zfilter.id = 1234U; zfilter.id = 1234U;
zfilter.rtr_mask = 1U; zfilter.mask = 1234U;
zfilter.id_mask = 1234U;
socketcan_from_can_filter(&zfilter, &sfilter); socketcan_from_can_filter(&zfilter, &sfilter);

View file

@ -233,9 +233,7 @@ static void send_frame_series(struct frame_desired *frames, size_t length,
{ {
int i, ret; int i, ret;
struct can_frame frame = { struct can_frame frame = {
.id_type = (id > 0x7FF) ? CAN_EXTENDED_IDENTIFIER : .flags = (id > 0x7FF) ? CAN_FRAME_IDE : 0,
CAN_STANDARD_IDENTIFIER,
.rtr = CAN_DATAFRAME,
.id = id .id = id
}; };
struct frame_desired *desired = frames; struct frame_desired *desired = frames;
@ -283,12 +281,9 @@ static int add_rx_msgq(uint32_t id, uint32_t mask)
{ {
int filter_id; int filter_id;
struct can_filter filter = { struct can_filter filter = {
.id_type = (id > 0x7FF) ? CAN_EXTENDED_IDENTIFIER : .flags = CAN_FILTER_DATA | ((id > 0x7FF) ? CAN_FILTER_IDE : 0),
CAN_STANDARD_IDENTIFIER,
.rtr = CAN_DATAFRAME,
.id = id, .id = id,
.rtr_mask = 1, .mask = mask
.id_mask = mask
}; };
filter_id = can_add_rx_filter_msgq(can_dev, &frame_msgq, &filter); filter_id = can_add_rx_filter_msgq(can_dev, &frame_msgq, &filter);