Skip to content

Commit d167d3a

Browse files
congnguyenhuudleach02
authored andcommitted
driver: can: add new filter to match CAN-FD frames
Add support FD frame filter to configure type frame for each Rx msg to receive corresponding frames (classic, FD frames). The Bosch M_CAN driver does not support FD frame filter, so inmplement driver to handle it in software. Signed-off-by: Cong Nguyen Huu <[email protected]>
1 parent 474a8cf commit d167d3a

File tree

8 files changed

+57
-6
lines changed

8 files changed

+57
-6
lines changed

drivers/can/can_loopback.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,12 @@ static int can_loopback_add_rx_filter(const struct device *dev, can_rx_callback_
173173

174174
LOG_DBG("Setting filter ID: 0x%x, mask: 0x%x", filter->id, filter->mask);
175175

176+
#ifdef CONFIG_CAN_FD_MODE
177+
if ((filter->flags & ~(CAN_FILTER_IDE | CAN_FILTER_DATA |
178+
CAN_FILTER_RTR | CAN_FILTER_FDF)) != 0) {
179+
#else
176180
if ((filter->flags & ~(CAN_FILTER_IDE | CAN_FILTER_DATA | CAN_FILTER_RTR)) != 0) {
181+
#endif
177182
LOG_ERR("unsupported CAN filter flags 0x%02x", filter->flags);
178183
return -ENOTSUP;
179184
}

drivers/can/can_mcan.c

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -618,6 +618,7 @@ static void can_mcan_get_message(const struct device *dev,
618618
struct can_mcan_rx_fifo_hdr hdr;
619619
bool rtr_filter_mask;
620620
bool rtr_filter;
621+
bool fd_frame_filter;
621622

622623
while ((*fifo_status_reg & CAN_MCAN_RXF0S_F0FL)) {
623624
get_idx = (*fifo_status_reg & CAN_MCAN_RXF0S_F0GI) >>
@@ -653,16 +654,22 @@ static void can_mcan_get_message(const struct device *dev,
653654
frame.flags |= CAN_FRAME_IDE;
654655
rtr_filter_mask = (data->ext_filt_rtr_mask & BIT(filt_idx)) != 0;
655656
rtr_filter = (data->ext_filt_rtr & BIT(filt_idx)) != 0;
657+
fd_frame_filter = (data->ext_filt_fd_frame & BIT(filt_idx)) != 0;
656658
} else {
657659
frame.id = hdr.std_id;
658660
rtr_filter_mask = (data->std_filt_rtr_mask & BIT(filt_idx)) != 0;
659661
rtr_filter = (data->std_filt_rtr & BIT(filt_idx)) != 0;
662+
fd_frame_filter = (data->std_filt_fd_frame & BIT(filt_idx)) != 0;
660663
}
661664

662665
if (rtr_filter_mask && (rtr_filter != ((frame.flags & CAN_FRAME_RTR) != 0))) {
663666
/* RTR bit does not match filter RTR mask, drop frame */
664667
*fifo_ack_reg = get_idx;
665668
continue;
669+
} else if (fd_frame_filter != ((frame.flags & CAN_FRAME_FDF) != 0)) {
670+
/* FD bit does not match filter FD frame, drop frame */
671+
*fifo_ack_reg = get_idx;
672+
continue;
666673
}
667674

668675
data_length = can_dlc_to_bytes(frame.dlc);
@@ -949,11 +956,6 @@ int can_mcan_add_rx_filter_std(const struct device *dev,
949956
};
950957
int filter_id;
951958

952-
if ((filter->flags & ~(CAN_FILTER_IDE | CAN_FILTER_DATA | CAN_FILTER_RTR)) != 0) {
953-
LOG_ERR("unsupported CAN filter flags 0x%02x", filter->flags);
954-
return -ENOTSUP;
955-
}
956-
957959
k_mutex_lock(&data->inst_mutex, K_FOREVER);
958960
filter_id = can_mcan_get_free_std(msg_ram->std_filt);
959961

@@ -988,6 +990,12 @@ int can_mcan_add_rx_filter_std(const struct device *dev,
988990
data->std_filt_rtr_mask &= ~(1U << filter_id);
989991
}
990992

993+
if ((filter->flags & CAN_FILTER_FDF) != 0) {
994+
data->std_filt_fd_frame |= (1U << filter_id);
995+
} else {
996+
data->std_filt_fd_frame &= ~(1U << filter_id);
997+
}
998+
991999
data->rx_cb_std[filter_id] = callback;
9921000
data->cb_arg_std[filter_id] = user_data;
9931001

@@ -1052,6 +1060,12 @@ static int can_mcan_add_rx_filter_ext(const struct device *dev,
10521060
data->ext_filt_rtr_mask &= ~(1U << filter_id);
10531061
}
10541062

1063+
if ((filter->flags & CAN_FILTER_FDF) != 0) {
1064+
data->ext_filt_fd_frame |= (1U << filter_id);
1065+
} else {
1066+
data->ext_filt_fd_frame &= ~(1U << filter_id);
1067+
}
1068+
10551069
data->rx_cb_ext[filter_id] = callback;
10561070
data->cb_arg_ext[filter_id] = user_data;
10571071

@@ -1068,6 +1082,17 @@ int can_mcan_add_rx_filter(const struct device *dev,
10681082
return -EINVAL;
10691083
}
10701084

1085+
1086+
#ifdef CONFIG_CAN_FD_MODE
1087+
if ((filter->flags & ~(CAN_FILTER_IDE | CAN_FILTER_DATA |
1088+
CAN_FILTER_RTR | CAN_FILTER_FDF)) != 0) {
1089+
#else
1090+
if ((filter->flags & ~(CAN_FILTER_IDE | CAN_FILTER_DATA | CAN_FILTER_RTR)) != 0) {
1091+
#endif
1092+
LOG_ERR("unsupported CAN filter flags 0x%02x", filter->flags);
1093+
return -ENOTSUP;
1094+
}
1095+
10711096
if ((filter->flags & CAN_FILTER_IDE) != 0) {
10721097
filter_id = can_mcan_add_rx_filter_ext(dev, callback, user_data, filter);
10731098
if (filter_id >= 0) {

drivers/can/can_mcan.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,8 +178,10 @@ struct can_mcan_data {
178178
void *cb_arg_ext[NUM_EXT_FILTER_DATA];
179179
can_state_change_callback_t state_change_cb;
180180
void *state_change_cb_data;
181+
uint32_t std_filt_fd_frame;
181182
uint32_t std_filt_rtr;
182183
uint32_t std_filt_rtr_mask;
184+
uint16_t ext_filt_fd_frame;
183185
uint16_t ext_filt_rtr;
184186
uint16_t ext_filt_rtr_mask;
185187
struct can_mcan_mm mm;

drivers/can/can_native_posix_linux.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,12 @@ static int can_npl_add_rx_filter(const struct device *dev, can_rx_callback_t cb,
199199
LOG_DBG("Setting filter ID: 0x%x, mask: 0x%x", filter->id,
200200
filter->mask);
201201

202+
#ifdef CONFIG_CAN_FD_MODE
203+
if ((filter->flags & ~(CAN_FILTER_IDE | CAN_FILTER_DATA |
204+
CAN_FILTER_RTR | CAN_FILTER_FDF)) != 0) {
205+
#else
202206
if ((filter->flags & ~(CAN_FILTER_IDE | CAN_FILTER_DATA | CAN_FILTER_RTR)) != 0) {
207+
#endif
203208
LOG_ERR("unsupported CAN filter flags 0x%02x", filter->flags);
204209
return -ENOTSUP;
205210
}

drivers/can/can_utils.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ static inline bool can_utils_filter_match(const struct can_frame *frame,
3333
return false;
3434
}
3535

36+
if (((frame->flags & CAN_FRAME_FDF) != 0) && (filter->flags & CAN_FILTER_FDF) == 0) {
37+
return false;
38+
}
39+
3640
if ((frame->id ^ filter->id) & filter->mask) {
3741
return false;
3842
}

include/zephyr/drivers/can.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,9 @@ struct can_frame {
196196
/** Filter matches data frames */
197197
#define CAN_FILTER_DATA BIT(2)
198198

199+
/** Filter matches CAN-FD frames (FDF) */
200+
#define CAN_FILTER_FDF BIT(3)
201+
199202
/** @} */
200203

201204
/**
@@ -212,7 +215,7 @@ struct can_filter {
212215
*/
213216
uint32_t mask : 29;
214217
/** Flags. @see @ref CAN_FILTER_FLAGS. */
215-
uint8_t flags : 3;
218+
uint8_t flags;
216219
};
217220

218221
/**

include/zephyr/net/socketcan.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,8 @@ struct socketcan_filter {
124124
socketcan_id_t can_id;
125125
/** The mask applied to @a can_id for matching. */
126126
socketcan_id_t can_mask;
127+
/** Additional flags for FD frame filter. */
128+
uint8_t flags;
127129
};
128130

129131
/** @} */

include/zephyr/net/socketcan_utils.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ static inline void socketcan_to_can_filter(const struct socketcan_filter *sfilte
8888
zfilter->flags |= (sfilter->can_id & BIT(31)) != 0 ? CAN_FILTER_IDE : 0;
8989
zfilter->id = sfilter->can_id & BIT_MASK(29);
9090
zfilter->mask = sfilter->can_mask & BIT_MASK(29);
91+
zfilter->flags |= (sfilter->flags & CANFD_FDF) != 0 ? CAN_FILTER_FDF : 0;
9192

9293
if ((sfilter->can_mask & BIT(30)) == 0) {
9394
zfilter->flags |= CAN_FILTER_DATA | CAN_FILTER_RTR;
@@ -120,6 +121,10 @@ static inline void socketcan_from_can_filter(const struct can_filter *zfilter,
120121
(CAN_FILTER_DATA | CAN_FILTER_RTR)) {
121122
sfilter->can_mask |= BIT(30);
122123
}
124+
125+
if ((zfilter->flags & CAN_FILTER_FDF) != 0) {
126+
sfilter->flags |= CANFD_FDF;
127+
}
123128
}
124129

125130
/**

0 commit comments

Comments
 (0)