Skip to content

Commit 874d77b

Browse files
henrikbrixandersencfriedt
authored andcommitted
drivers: can: mcux: flexcan: fix handling of RTR frames
When installing a RX filter, the driver uses "filter->rtr & filter->rtr_mask" for setting the filter mask. It should just be using filter->rtr_mask, otherwise filters for non-RTR frames will match RTR frames as well. When transmitting a RTR frame, the hardware automatically switches the mailbox used for TX to RX in order to receive the reply. This, however, does not match the Zephyr CAN driver model, where mailboxes are dedicated to either RX or TX. Attempting to reuse the TX mailbox (which was automatically switched to an RX mailbox by the hardware) fails on the first call, after which the mailbox is reset and can be reused for TX. To overcome this, the driver must abort the RX mailbox operation when the hardware performs the TX to RX switch. Fixes: #47902 Signed-off-by: Henrik Brix Andersen <[email protected]>
1 parent ec0befb commit 874d77b

File tree

1 file changed

+4
-4
lines changed

1 file changed

+4
-4
lines changed

drivers/can/can_mcux_flexcan.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -253,13 +253,11 @@ static void mcux_flexcan_copy_zfilter_to_mbconfig(const struct zcan_filter *src,
253253
if (src->id_type == CAN_STANDARD_IDENTIFIER) {
254254
dest->format = kFLEXCAN_FrameFormatStandard;
255255
dest->id = FLEXCAN_ID_STD(src->id);
256-
*mask = FLEXCAN_RX_MB_STD_MASK(src->id_mask,
257-
src->rtr & src->rtr_mask, 1);
256+
*mask = FLEXCAN_RX_MB_STD_MASK(src->id_mask, src->rtr_mask, 1);
258257
} else {
259258
dest->format = kFLEXCAN_FrameFormatExtend;
260259
dest->id = FLEXCAN_ID_EXT(src->id);
261-
*mask = FLEXCAN_RX_MB_EXT_MASK(src->id_mask,
262-
src->rtr & src->rtr_mask, 1);
260+
*mask = FLEXCAN_RX_MB_EXT_MASK(src->id_mask, src->rtr_mask, 1);
263261
}
264262

265263
if ((src->rtr & src->rtr_mask) == CAN_DATAFRAME) {
@@ -646,6 +644,7 @@ static inline void mcux_flexcan_transfer_rx_idle(const struct device *dev,
646644
static FLEXCAN_CALLBACK(mcux_flexcan_transfer_callback)
647645
{
648646
struct mcux_flexcan_data *data = (struct mcux_flexcan_data *)userData;
647+
const struct mcux_flexcan_config *config = data->dev->config;
649648

650649
switch (status) {
651650
case kStatus_FLEXCAN_UnHandled:
@@ -654,6 +653,7 @@ static FLEXCAN_CALLBACK(mcux_flexcan_transfer_callback)
654653
mcux_flexcan_transfer_error_status(data->dev, (uint64_t)result);
655654
break;
656655
case kStatus_FLEXCAN_TxSwitchToRx:
656+
FLEXCAN_TransferAbortReceive(config->base, &data->handle, (uint64_t)result);
657657
__fallthrough;
658658
case kStatus_FLEXCAN_TxIdle:
659659
/* The result field is a MB value which is limited to 32bit value */

0 commit comments

Comments
 (0)