drivers: can: rework zcan_frame and zcan_filter

Reordering of the struct elements to match the Linux format.
The __packed() is not necessary anymore.
std_id and ext_id is merged to id in the frame and filter.
Additionally, the frames are ready for CAN-FD.

Signed-off-by: Alexander Wachter <alexander@wachter.cloud>
This commit is contained in:
Alexander Wachter 2020-11-19 20:46:56 +01:00 committed by Carles Cufí
commit 05275ecf6e
17 changed files with 206 additions and 235 deletions

View file

@ -6,12 +6,12 @@
#include <drivers/can.h>
#include <kernel.h>
#include <sys/util.h>
#define LOG_LEVEL CONFIG_CAN_LOG_LEVEL
#include <logging/log.h>
LOG_MODULE_REGISTER(can_driver);
#define CAN_CLAMP(val, min, max) MIN(MAX(val, min), max)
#define CAN_SYNC_SEG 1
#define WORK_BUF_COUNT_IS_POWER_OF_2 !(CONFIG_CAN_WORKQ_FRAMES_BUF_CNT & \
@ -36,9 +36,7 @@ static void can_msgq_put(struct zcan_frame *frame, void *arg)
ret = k_msgq_put(msgq, frame, K_NO_WAIT);
if (ret) {
LOG_ERR("Msgq %p overflowed. Frame ID: 0x%x", arg,
frame->id_type == CAN_STANDARD_IDENTIFIER ?
frame->std_id : frame->ext_id);
LOG_ERR("Msgq %p overflowed. Frame ID: 0x%x", arg, frame->id);
}
}
@ -122,9 +120,7 @@ static void can_work_isr_put(struct zcan_frame *frame, void *arg)
ret = can_work_buffer_put(frame, &work->buf);
if (ret) {
LOG_ERR("Workq buffer overflow. Msg ID: 0x%x",
frame->id_type == CAN_STANDARD_IDENTIFIER ?
frame->std_id : frame->ext_id);
LOG_ERR("Workq buffer overflow. Msg ID: 0x%x", frame->id);
return;
}
@ -175,7 +171,7 @@ static int update_sampling_pnt(uint32_t ts, uint32_t sp, struct can_timing *res,
}
}
res->prop_seg = CAN_CLAMP(ts1 / 2, min->prop_seg, max->prop_seg);
res->prop_seg = CLAMP(ts1 / 2, min->prop_seg, max->prop_seg);
res->phase_seg1 = ts1 - res->prop_seg;
res->phase_seg2 = ts2;

View file

@ -33,9 +33,7 @@ static void dispatch_frame(const struct zcan_frame *frame,
struct zcan_frame frame_tmp = *frame;
LOG_DBG("Receiving %d bytes. Id: 0x%x, ID type: %s %s",
frame->dlc,
frame->id_type == CAN_STANDARD_IDENTIFIER ?
frame->std_id : frame->ext_id,
frame->dlc, frame->id,
frame->id_type == CAN_STANDARD_IDENTIFIER ?
"standard" : "extended",
frame->rtr == CAN_DATAFRAME ? "" : ", RTR frame");
@ -46,16 +44,8 @@ static void dispatch_frame(const struct zcan_frame *frame,
static inline int check_filter_match(const struct zcan_frame *frame,
const struct zcan_filter *filter)
{
uint32_t id, mask, frame_id;
frame_id = frame->id_type == CAN_STANDARD_IDENTIFIER ?
frame->std_id : frame->ext_id;
id = filter->id_type == CAN_STANDARD_IDENTIFIER ?
filter->std_id : filter->ext_id;
mask = filter->id_type == CAN_STANDARD_IDENTIFIER ?
filter->std_id_mask : filter->ext_id_mask;
return ((id & mask) == (frame_id & mask));
return ((filter->id & filter->id_mask) ==
(frame->id & filter->id_mask));
}
void tx_thread(void *data_arg, void *arg2, void *arg3)
@ -99,9 +89,7 @@ int can_loopback_send(const struct device *dev,
struct k_sem tx_sem;
LOG_DBG("Sending %d bytes on %s. Id: 0x%x, ID type: %s %s",
frame->dlc, dev->name,
frame->id_type == CAN_STANDARD_IDENTIFIER ?
frame->std_id : frame->ext_id,
frame->dlc, dev->name, frame->id,
frame->id_type == CAN_STANDARD_IDENTIFIER ?
"standard" : "extended",
frame->rtr == CAN_DATAFRAME ? "" : ", RTR frame");
@ -153,14 +141,14 @@ int can_loopback_attach_isr(const struct device *dev, can_rx_callback_t isr,
struct can_loopback_filter *loopback_filter;
int filter_id;
LOG_DBG("Setting filter ID: 0x%x, mask: 0x%x", filter->ext_id,
filter->ext_id_mask);
LOG_DBG("Setting filter ID: 0x%x, mask: 0x%x", filter->id,
filter->id_mask);
LOG_DBG("Filter type: %s ID %s mask",
filter->id_type == CAN_STANDARD_IDENTIFIER ?
"standard" : "extended",
((filter->id_type && (filter->std_id_mask == CAN_STD_ID_MASK)) ||
(!filter->id_type && (filter->ext_id_mask == CAN_EXT_ID_MASK))) ?
"with" : "without");
filter->id_type == CAN_STANDARD_IDENTIFIER ?
"standard" : "extended",
((filter->id_type && (filter->id_mask == CAN_STD_ID_MASK)) ||
(!filter->id_type && (filter->id_mask == CAN_EXT_ID_MASK))) ?
"with" : "without");
k_mutex_lock(&data->mtx, K_FOREVER);
filter_id = get_free_filter(data->filters);

View file

@ -202,16 +202,16 @@ static void mcp2515_convert_zcanframe_to_mcp2515frame(const struct zcan_frame
uint8_t data_idx = 0U;
if (source->id_type == CAN_STANDARD_IDENTIFIER) {
target[MCP2515_FRAME_OFFSET_SIDH] = source->std_id >> 3;
target[MCP2515_FRAME_OFFSET_SIDH] = source->id >> 3;
target[MCP2515_FRAME_OFFSET_SIDL] =
(source->std_id & 0x07) << 5;
(source->id & 0x07) << 5;
} else {
target[MCP2515_FRAME_OFFSET_SIDH] = source->ext_id >> 21;
target[MCP2515_FRAME_OFFSET_SIDH] = source->id >> 21;
target[MCP2515_FRAME_OFFSET_SIDL] =
(((source->ext_id >> 18) & 0x07) << 5) | (BIT(3)) |
((source->ext_id >> 16) & 0x03);
target[MCP2515_FRAME_OFFSET_EID8] = source->ext_id >> 8;
target[MCP2515_FRAME_OFFSET_EID0] = source->ext_id;
(((source->id >> 18) & 0x07) << 5) | (BIT(3)) |
((source->id >> 16) & 0x03);
target[MCP2515_FRAME_OFFSET_EID8] = source->id >> 8;
target[MCP2515_FRAME_OFFSET_EID0] = source->id;
}
rtr = (source->rtr == CAN_REMOTEREQUEST) ? BIT(6) : 0;
@ -232,7 +232,7 @@ static void mcp2515_convert_mcp2515frame_to_zcanframe(const uint8_t *source,
if (source[MCP2515_FRAME_OFFSET_SIDL] & BIT(3)) {
target->id_type = CAN_EXTENDED_IDENTIFIER;
target->ext_id =
target->id =
(source[MCP2515_FRAME_OFFSET_SIDH] << 21) |
((source[MCP2515_FRAME_OFFSET_SIDL] >> 5) << 18) |
((source[MCP2515_FRAME_OFFSET_SIDL] & 0x03) << 16) |
@ -240,7 +240,7 @@ static void mcp2515_convert_mcp2515frame_to_zcanframe(const uint8_t *source,
source[MCP2515_FRAME_OFFSET_EID0];
} else {
target->id_type = CAN_STANDARD_IDENTIFIER;
target->std_id = (source[MCP2515_FRAME_OFFSET_SIDH] << 3) |
target->id = (source[MCP2515_FRAME_OFFSET_SIDH] << 3) |
(source[MCP2515_FRAME_OFFSET_SIDL] >> 5);
}
@ -556,14 +556,8 @@ static uint8_t mcp2515_filter_match(struct zcan_frame *msg,
return 0;
}
if (msg->id_type == CAN_STANDARD_IDENTIFIER) {
if ((msg->std_id ^ filter->std_id) & filter->std_id_mask) {
return 0;
}
} else {
if ((msg->ext_id ^ filter->ext_id) & filter->ext_id_mask) {
return 0;
}
if ((msg->id ^ filter->id) & filter->id_mask) {
return 0;
}
return 1;

View file

@ -177,10 +177,10 @@ static void mcux_flexcan_copy_zframe_to_frame(const struct zcan_frame *src,
{
if (src->id_type == CAN_STANDARD_IDENTIFIER) {
dest->format = kFLEXCAN_FrameFormatStandard;
dest->id = FLEXCAN_ID_STD(src->std_id);
dest->id = FLEXCAN_ID_STD(src->id);
} else {
dest->format = kFLEXCAN_FrameFormatExtend;
dest->id = FLEXCAN_ID_EXT(src->ext_id);
dest->id = FLEXCAN_ID_EXT(src->id);
}
if (src->rtr == CAN_DATAFRAME) {
@ -199,10 +199,10 @@ static void mcux_flexcan_copy_frame_to_zframe(const flexcan_frame_t *src,
{
if (src->format == kFLEXCAN_FrameFormatStandard) {
dest->id_type = CAN_STANDARD_IDENTIFIER;
dest->std_id = FLEXCAN_ID_TO_ZCAN_ID_STD(src->id);
dest->id = FLEXCAN_ID_TO_ZCAN_ID_STD(src->id);
} else {
dest->id_type = CAN_EXTENDED_IDENTIFIER;
dest->ext_id = FLEXCAN_ID_TO_ZCAN_ID_EXT(src->id);
dest->id = FLEXCAN_ID_TO_ZCAN_ID_EXT(src->id);
}
if (src->type == kFLEXCAN_FrameTypeData) {
@ -225,13 +225,13 @@ static void mcux_flexcan_copy_zfilter_to_mbconfig(const struct zcan_filter *src,
{
if (src->id_type == CAN_STANDARD_IDENTIFIER) {
dest->format = kFLEXCAN_FrameFormatStandard;
dest->id = FLEXCAN_ID_STD(src->std_id);
*mask = FLEXCAN_RX_MB_STD_MASK(src->std_id_mask,
dest->id = FLEXCAN_ID_STD(src->id);
*mask = FLEXCAN_RX_MB_STD_MASK(src->id_mask,
src->rtr & src->rtr_mask, 1);
} else {
dest->format = kFLEXCAN_FrameFormatExtend;
dest->id = FLEXCAN_ID_EXT(src->ext_id);
*mask = FLEXCAN_RX_MB_EXT_MASK(src->ext_id_mask,
dest->id = FLEXCAN_ID_EXT(src->id);
*mask = FLEXCAN_RX_MB_EXT_MASK(src->id_mask,
src->rtr & src->rtr_mask, 1);
}

View file

@ -50,16 +50,16 @@ static inline uint8_t can_get_frame_datalength(struct zcan_frame *frame)
static inline uint16_t can_get_lladdr_src(struct zcan_frame *frame)
{
return (frame->ext_id >> CAN_NET_IF_ADDR_SRC_POS) &
return (frame->id >> CAN_NET_IF_ADDR_SRC_POS) &
CAN_NET_IF_ADDR_MASK;
}
static inline uint16_t can_get_lladdr_dest(struct zcan_frame *frame)
{
uint16_t addr = (frame->ext_id >> CAN_NET_IF_ADDR_DEST_POS) &
uint16_t addr = (frame->id >> CAN_NET_IF_ADDR_DEST_POS) &
CAN_NET_IF_ADDR_MASK;
if (frame->ext_id & CAN_NET_IF_ADDR_MCAST_MASK) {
if (frame->id & CAN_NET_IF_ADDR_MCAST_MASK) {
addr |= CAN_NET_IF_IS_MCAST_BIT;
}
@ -106,7 +106,7 @@ static void net_can_recv(struct zcan_frame *frame, void *arg)
struct net_pkt *pkt;
int ret;
NET_DBG("Frame with ID 0x%x received", frame->ext_id);
NET_DBG("Frame with ID 0x%x received", frame->id);
pkt = net_pkt_rx_alloc_with_buffer(ctx->iface, pkt_size, AF_UNSPEC, 0,
K_NO_WAIT);
if (!pkt) {
@ -147,14 +147,14 @@ static inline int attach_mcast_filter(struct net_can_context *ctx,
.id_type = CAN_EXTENDED_IDENTIFIER,
.rtr = CAN_DATAFRAME,
.rtr_mask = 1,
.ext_id_mask = CAN_NET_IF_ADDR_MCAST_MASK |
.id_mask = CAN_NET_IF_ADDR_MCAST_MASK |
CAN_NET_IF_ADDR_DEST_MASK
};
const uint16_t group =
sys_be16_to_cpu(UNALIGNED_GET((&addr->s6_addr16[7])));
int filter_id;
filter.ext_id = CAN_NET_IF_ADDR_MCAST_MASK |
filter.id = CAN_NET_IF_ADDR_MCAST_MASK |
((group & CAN_NET_IF_ADDR_MASK) <<
CAN_NET_IF_ADDR_DEST_POS);
@ -242,13 +242,13 @@ static inline int can_attach_unicast_filter(struct net_can_context *ctx)
.id_type = CAN_EXTENDED_IDENTIFIER,
.rtr = CAN_DATAFRAME,
.rtr_mask = 1,
.ext_id_mask = CAN_NET_IF_ADDR_DEST_MASK
.id_mask = CAN_NET_IF_ADDR_DEST_MASK
};
const uint8_t *link_addr = net_if_get_link_addr(ctx->iface)->addr;
const uint16_t dest = sys_be16_to_cpu(UNALIGNED_GET((uint16_t *) link_addr));
int filter_id;
filter.ext_id = (dest << CAN_NET_IF_ADDR_DEST_POS);
filter.id = (dest << CAN_NET_IF_ADDR_DEST_POS);
filter_id = can_attach_isr(ctx->can_dev, net_can_recv,
ctx, &filter);
@ -269,8 +269,8 @@ static inline int can_attach_eth_bridge_filter(struct net_can_context *ctx)
.id_type = CAN_EXTENDED_IDENTIFIER,
.rtr = CAN_DATAFRAME,
.rtr_mask = 1,
.ext_id_mask = CAN_NET_IF_ADDR_DEST_MASK,
.ext_id = (NET_CAN_ETH_TRANSLATOR_ADDR <<
.id_mask = CAN_NET_IF_ADDR_DEST_MASK,
.id = (NET_CAN_ETH_TRANSLATOR_ADDR <<
CAN_NET_IF_ADDR_DEST_POS)
};
@ -294,8 +294,8 @@ static inline int can_attach_all_mcast_filter(struct net_can_context *ctx)
.id_type = CAN_EXTENDED_IDENTIFIER,
.rtr = CAN_DATAFRAME,
.rtr_mask = 1,
.ext_id_mask = CAN_NET_IF_ADDR_MCAST_MASK,
.ext_id = CAN_NET_IF_ADDR_MCAST_MASK
.id_mask = CAN_NET_IF_ADDR_MCAST_MASK,
.id = CAN_NET_IF_ADDR_MCAST_MASK
};
int filter_id;

View file

@ -190,8 +190,7 @@ static void print_frame(struct zcan_frame *frame, void *arg)
const struct shell *shell = (const struct shell *)arg;
shell_fprintf(shell, SHELL_NORMAL, "|0x%-8x|%s|%s|%d|",
frame->id_type == CAN_STANDARD_IDENTIFIER ?
frame->std_id : frame->ext_id,
frame->id,
frame->id_type == CAN_STANDARD_IDENTIFIER ? "std" : "ext",
frame->rtr ? "RTR" : " ", frame->dlc);
@ -293,7 +292,7 @@ static int cmd_send(const struct shell *shell, size_t argc, char **argv)
return -EINVAL;
}
frame.ext_id = id;
frame.id = id;
pos = read_data(shell, pos, argv, argc, frame.data, &frame.dlc);
if (pos < 0) {
@ -301,8 +300,7 @@ static int cmd_send(const struct shell *shell, size_t argc, char **argv)
}
shell_print(shell, "Send frame with ID 0x%x (%s id) and %d data bytes",
ext ? frame.ext_id : frame.std_id,
ext ? "extended" : "standard", frame.dlc);
frame.id, ext ? "extended" : "standard", frame.dlc);
ret = can_send(can_dev, &frame, K_FOREVER, NULL, NULL);
if (ret) {
@ -344,16 +342,16 @@ static int cmd_attach(const struct shell *shell, size_t argc, char **argv)
return -EINVAL;
}
filter.ext_id = id;
filter.id = id;
if (pos != argc) {
pos = read_mask(shell, pos, argv, ext, &mask);
if (pos < 0) {
return -EINVAL;
}
filter.ext_id_mask = mask;
filter.id_mask = mask;
} else {
filter.ext_id_mask = ext ? CAN_EXT_ID_MASK : CAN_STD_ID_MASK;
filter.id_mask = ext ? CAN_EXT_ID_MASK : CAN_STD_ID_MASK;
}
if (pos != argc) {
@ -367,9 +365,7 @@ static int cmd_attach(const struct shell *shell, size_t argc, char **argv)
shell_print(shell, "Attach filter with ID 0x%x (%s id) and mask 0x%x "
" RTR: %d",
ext ? filter.ext_id : filter.std_id,
ext ? "extended" : "standard",
ext ? filter.ext_id_mask : filter.std_id_mask,
filter.id, ext ? "extended" : "standard", filter.id_mask,
filter.rtr_mask);
ret = can_attach_workq(can_dev, &k_sys_work_q, &work, print_frame,

View file

@ -47,10 +47,10 @@ static void can_stm32_get_msg_fifo(CAN_FIFOMailBox_TypeDef *mbox,
struct zcan_frame *msg)
{
if (mbox->RIR & CAN_RI0R_IDE) {
msg->ext_id = mbox->RIR >> CAN_RI0R_EXID_Pos;
msg->id = mbox->RIR >> CAN_RI0R_EXID_Pos;
msg->id_type = CAN_EXTENDED_IDENTIFIER;
} else {
msg->std_id = mbox->RIR >> CAN_RI0R_STID_Pos;
msg->id = mbox->RIR >> CAN_RI0R_STID_Pos;
msg->id_type = CAN_STANDARD_IDENTIFIER;
}
@ -603,8 +603,7 @@ int can_stm32_send(const struct device *dev, const struct zcan_frame *msg,
"ID type: %s, "
"Remote Frame: %s"
, msg->dlc, dev->name
, msg->id_type == CAN_STANDARD_IDENTIFIER ?
msg->std_id : msg->ext_id
, msg->id
, msg->id_type == CAN_STANDARD_IDENTIFIER ?
"standard" : "extended"
, msg->rtr == CAN_DATAFRAME ? "no" : "yes");
@ -654,9 +653,9 @@ int can_stm32_send(const struct device *dev, const struct zcan_frame *msg,
mailbox->TIR &= CAN_TI0R_TXRQ;
if (msg->id_type == CAN_STANDARD_IDENTIFIER) {
mailbox->TIR |= (msg->std_id << CAN_TI0R_STID_Pos);
mailbox->TIR |= (msg->id << CAN_TI0R_STID_Pos);
} else {
mailbox->TIR |= (msg->ext_id << CAN_TI0R_EXID_Pos)
mailbox->TIR |= (msg->id << CAN_TI0R_EXID_Pos)
| CAN_TI0R_IDE;
}
@ -836,31 +835,31 @@ static inline void can_stm32_set_mode_scale(enum can_filter_type filter_type,
static inline uint32_t can_generate_std_mask(const struct zcan_filter *filter)
{
return (filter->std_id_mask << CAN_FIRX_STD_ID_POS) |
(filter->rtr_mask << CAN_FIRX_STD_RTR_POS) |
(1U << CAN_FIRX_STD_IDE_POS);
return (filter->id_mask << CAN_FIRX_STD_ID_POS) |
(filter->rtr_mask << CAN_FIRX_STD_RTR_POS) |
(1U << CAN_FIRX_STD_IDE_POS);
}
static inline uint32_t can_generate_ext_mask(const struct zcan_filter *filter)
{
return (filter->ext_id_mask << CAN_FIRX_EXT_EXT_ID_POS) |
(filter->rtr_mask << CAN_FIRX_EXT_RTR_POS) |
(1U << CAN_FIRX_EXT_IDE_POS);
return (filter->id_mask << CAN_FIRX_EXT_EXT_ID_POS) |
(filter->rtr_mask << CAN_FIRX_EXT_RTR_POS) |
(1U << CAN_FIRX_EXT_IDE_POS);
}
static inline uint32_t can_generate_std_id(const struct zcan_filter *filter)
{
return (filter->std_id << CAN_FIRX_STD_ID_POS) |
return (filter->id << CAN_FIRX_STD_ID_POS) |
(filter->rtr << CAN_FIRX_STD_RTR_POS);
}
static inline uint32_t can_generate_ext_id(const struct zcan_filter *filter)
{
return (filter->ext_id << CAN_FIRX_EXT_EXT_ID_POS) |
(filter->rtr << CAN_FIRX_EXT_RTR_POS) |
(1U << CAN_FIRX_EXT_IDE_POS);
return (filter->id << CAN_FIRX_EXT_EXT_ID_POS) |
(filter->rtr << CAN_FIRX_EXT_RTR_POS) |
(1U << CAN_FIRX_EXT_IDE_POS);
}
static inline int can_stm32_set_filter(const struct zcan_filter *filter,
@ -882,7 +881,7 @@ static inline int can_stm32_set_filter(const struct zcan_filter *filter,
id = can_generate_std_id(filter);
filter_type = CAN_FILTER_STANDARD;
if (filter->std_id_mask != CAN_STD_ID_MASK) {
if (filter->id_mask != CAN_STD_ID_MASK) {
mask = can_generate_std_mask(filter);
filter_type = CAN_FILTER_STANDARD_MASKED;
}
@ -890,7 +889,7 @@ static inline int can_stm32_set_filter(const struct zcan_filter *filter,
id = can_generate_ext_id(filter);
filter_type = CAN_FILTER_EXTENDED;
if (filter->ext_id_mask != CAN_EXT_ID_MASK) {
if (filter->id_mask != CAN_EXT_ID_MASK) {
mask = can_generate_ext_mask(filter);
filter_type = CAN_FILTER_EXTENDED_MASKED;
}
@ -898,8 +897,8 @@ static inline int can_stm32_set_filter(const struct zcan_filter *filter,
register_demand = reg_demand[filter_type];
LOG_DBG("Setting filter ID: 0x%x, mask: 0x%x", filter->ext_id,
filter->ext_id_mask);
LOG_DBG("Setting filter ID: 0x%x, mask: 0x%x", filter->id,
filter->id_mask);
LOG_DBG("Filter type: %s ID %s mask (%d)",
(filter_type == CAN_FILTER_STANDARD ||
filter_type == CAN_FILTER_STANDARD_MASKED) ?