drivers: can: move CAN utility function to public header

Rename the can_utils_filter_match() utility function to
can_frame_matches_filter(), move it to the public
include/zephyr/drivers/can.h header file, and add a missing mismatch for
standard (11-bit) ID frames passing extended (29-bit) filters.

This allows using the utility function in out-of-tree CAN drivers.

Signed-off-by: Henrik Brix Andersen <hebad@vestas.com>
This commit is contained in:
Henrik Brix Andersen 2023-02-07 10:26:19 +01:00 committed by Carles Cufí
parent 00e6c19ab5
commit 36bffb20ae
7 changed files with 54 additions and 62 deletions

View file

@ -14,8 +14,6 @@
#include <zephyr/kernel.h>
#include <zephyr/logging/log.h>
#include "can_utils.h"
LOG_MODULE_REGISTER(can_loopback, CONFIG_CAN_LOG_LEVEL);
struct can_loopback_frame {
@ -88,7 +86,7 @@ static void tx_thread(void *arg1, void *arg2, void *arg3)
for (int i = 0; i < CONFIG_CAN_MAX_FILTER; i++) {
filter = &data->filters[i];
if (filter->rx_cb != NULL &&
can_utils_filter_match(&frame.frame, &filter->filter)) {
can_frame_matches_filter(&frame.frame, &filter->filter)) {
receive_frame(dev, &frame.frame, filter);
}
}

View file

@ -16,7 +16,6 @@
LOG_MODULE_REGISTER(can_mcp2515, CONFIG_CAN_LOG_LEVEL);
#include "can_mcp2515.h"
#include "can_utils.h"
#define SP_IS_SET(inst) DT_INST_NODE_HAS_PROP(inst, sample_point) ||
@ -704,8 +703,7 @@ static void mcp2515_rx_filter(const struct device *dev,
continue; /* filter slot empty */
}
if (!can_utils_filter_match(frame,
&dev_data->filter[filter_id])) {
if (!can_frame_matches_filter(frame, &dev_data->filter[filter_id])) {
continue; /* filter did not match */
}

View file

@ -17,7 +17,6 @@
#include <zephyr/net/socketcan.h>
#include <zephyr/net/socketcan_utils.h>
#include "can_utils.h"
#include "can_native_posix_linux_socketcan.h"
LOG_MODULE_REGISTER(can_npl, CONFIG_CAN_LOG_LEVEL);
@ -60,8 +59,7 @@ static void dispatch_frame(const struct device *dev, struct can_frame *frame)
continue;
}
if (!can_utils_filter_match(frame,
&data->filters[filter_id].filter)) {
if (!can_frame_matches_filter(frame, &data->filters[filter_id].filter)) {
continue;
}

View file

@ -18,8 +18,6 @@
LOG_MODULE_REGISTER(can_rcar, CONFIG_CAN_LOG_LEVEL);
#include "can_utils.h"
/* Control Register */
#define RCAR_CAN_CTLR 0x0840
/* Control Register bits */
@ -374,8 +372,7 @@ static void can_rcar_rx_filter_isr(const struct device *dev,
continue;
}
if (!can_utils_filter_match(frame,
&data->filter[i])) {
if (!can_frame_matches_filter(frame, &data->filter[i])) {
continue; /* filter did not match */
}
/* Make a temporary copy in case the user

View file

@ -6,7 +6,6 @@
#include "can_sja1000.h"
#include "can_sja1000_priv.h"
#include "can_utils.h"
#include <zephyr/drivers/can.h>
#include <zephyr/drivers/can/transceiver.h>
@ -573,7 +572,7 @@ static void can_sja1000_handle_receive_irq(const struct device *dev)
continue;
}
if (can_utils_filter_match(&frame, &data->filters[i].filter)) {
if (can_frame_matches_filter(&frame, &data->filters[i].filter)) {
callback = data->filters[i].callback;
if (callback != NULL) {
callback(dev, &frame, data->filters[i].user_data);

View file

@ -1,47 +0,0 @@
/*
* Copyright (c) 2018 Karsten Koenig
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file Header where utility code can be found for CAN drivers
*/
#ifndef ZEPHYR_DRIVERS_CAN_CAN_UTILS_H_
#define ZEPHYR_DRIVERS_CAN_CAN_UTILS_H_
/**
* @brief Check if a CAN filter matches a CAN frame
*
* @param frame CAN frame.
* @param filter CAN filter.
* @return true if the CAN filter matches the CAN frame, false otherwise
*/
static inline bool can_utils_filter_match(const struct can_frame *frame,
struct can_filter *filter)
{
if (((frame->flags & CAN_FRAME_IDE) != 0) && ((filter->flags & CAN_FILTER_IDE) == 0)) {
return false;
}
if (((frame->flags & CAN_FRAME_RTR) == 0) && (filter->flags & CAN_FILTER_DATA) == 0) {
return false;
}
if (((frame->flags & CAN_FRAME_RTR) != 0) && (filter->flags & CAN_FILTER_RTR) == 0) {
return false;
}
if (((frame->flags & CAN_FRAME_FDF) != 0) && (filter->flags & CAN_FILTER_FDF) == 0) {
return false;
}
if ((frame->id ^ filter->id) & filter->mask) {
return false;
}
return true;
}
#endif /* ZEPHYR_DRIVERS_CAN_CAN_UTILS_H_ */

View file

@ -1,5 +1,6 @@
/*
* Copyright (c) 2021 Vestas Wind Systems A/S
* Copyright (c) 2018 Karsten Koenig
* Copyright (c) 2018 Alexander Wachter
*
* SPDX-License-Identifier: Apache-2.0
@ -1379,6 +1380,54 @@ static inline uint8_t can_bytes_to_dlc(uint8_t num_bytes)
15;
}
/**
* @brief Check if a CAN frame matches a CAN filter
*
* @param frame CAN frame.
* @param filter CAN filter.
* @return true if the CAN frame matches the CAN filter, false otherwise
*/
static inline bool can_frame_matches_filter(const struct can_frame *frame,
const struct can_filter *filter)
{
if ((frame->flags & CAN_FRAME_IDE) != 0 && (filter->flags & CAN_FILTER_IDE) == 0) {
/* Extended (29-bit) ID frame, standard (11-bit) filter */
return false;
}
if ((frame->flags & CAN_FRAME_IDE) == 0 && (filter->flags & CAN_FILTER_IDE) != 0) {
/* Standard (11-bit) ID frame, extended (29-bit) filter */
return false;
}
if ((frame->flags & CAN_FRAME_RTR) == 0 && (filter->flags & CAN_FILTER_DATA) == 0) {
/* non-RTR frame, remote transmission request (RTR) filter */
return false;
}
if ((frame->flags & CAN_FRAME_RTR) != 0 && (filter->flags & CAN_FILTER_RTR) == 0) {
/* Remote transmission request (RTR) frame, non-RTR filter */
return false;
}
if ((frame->flags & CAN_FRAME_FDF) != 0 && (filter->flags & CAN_FILTER_FDF) == 0) {
/* CAN-FD format frame, classic format filter */
return false;
}
if ((frame->flags & CAN_FRAME_FDF) == 0 && (filter->flags & CAN_FILTER_FDF) != 0) {
/* Classic frame, CAN-FD format filter */
return false;
}
if ((frame->id ^ filter->id) & filter->mask) {
/* Masked ID mismatch */
return false;
}
return true;
}
/** @} */
/**