summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCYFS <[email protected]>2026-08-25 15:39:43 +0800
committerRbb666 <[email protected]>2026-09-01 09:16:54 +0800
commit7a2af55ffb3632b73ebfc29f01bf9889ed9d1979 (patch)
tree3f03bafd62815cade2d2c8c28887d00e1bdb74e4
parentf4da5cf14c059d1cdf32f1275880eddfafe4c159 (diff)
[bsp/renesas][drivers] Support configurable CAN FD operation
-rw-r--r--bsp/renesas/libraries/HAL_Drivers/drivers/drv_can.c403
1 files changed, 380 insertions, 23 deletions
diff --git a/bsp/renesas/libraries/HAL_Drivers/drivers/drv_can.c b/bsp/renesas/libraries/HAL_Drivers/drivers/drv_can.c
index fdf0ae2424..15d541dac9 100644
--- a/bsp/renesas/libraries/HAL_Drivers/drivers/drv_can.c
+++ b/bsp/renesas/libraries/HAL_Drivers/drivers/drv_can.c
@@ -11,6 +11,11 @@
#include "drv_can.h"
+#if defined(BSP_USING_CANFD) && defined(BSP_FEATURE_CANFD_HAS_CLOCK) && \
+ BSP_FEATURE_CANFD_HAS_CLOCK
+#define RA_CAN_USING_DYNAMIC_CANFD_TIMING
+#endif
+
static struct ra_can_config can_config[] =
{
#ifdef BSP_USING_CAN0
@@ -35,6 +40,7 @@ enum
static struct ra_can can_obj[sizeof(can_config) / sizeof(can_config[0])] = {0};
+#ifndef RA_CAN_USING_DYNAMIC_CANFD_TIMING
static const struct ra_baud_rate_tab can_baud_rate_tab[] =
{
{CAN1MBaud, 3, 6, 3, 1 + 4},
@@ -47,6 +53,7 @@ static const struct ra_baud_rate_tab can_baud_rate_tab[] =
{CAN20kBaud, 4, 14, 5, 1 + 124},
{CAN10kBaud, 4, 14, 5, 1 + 249}
};
+#endif
#if defined(BSP_USING_CANFD)
@@ -57,10 +64,12 @@ static const struct ra_baud_rate_tab can_baud_rate_tab[] =
#define R_CAN_ModeTransition R_CANFD_ModeTransition
#define R_CAN_InfoGet R_CANFD_InfoGet
#define R_CAN_Write R_CANFD_Write
+#define R_CAN_Close R_CANFD_Close
#define can0_callback canfd0_callback
#define can1_callback canfd1_callback
+#ifdef BSP_USING_CAN0
const canfd_afl_entry_t p_canfd0_afl[CANFD_CFG_AFL_CH0_RULE_NUM] =
{
{
@@ -78,7 +87,9 @@ const canfd_afl_entry_t p_canfd0_afl[CANFD_CFG_AFL_CH0_RULE_NUM] =
}
},
};
+#endif
+#ifdef BSP_USING_CAN1
const canfd_afl_entry_t p_canfd1_afl[CANFD_CFG_AFL_CH1_RULE_NUM] =
{
{
@@ -92,13 +103,19 @@ const canfd_afl_entry_t p_canfd1_afl[CANFD_CFG_AFL_CH1_RULE_NUM] =
{
.minimum_dlc = CANFD_MINIMUM_DLC_1,
.rx_buffer = CANFD_RX_MB_NONE,
+#if defined(BSP_FEATURE_CANFD_NUM_INSTANCES) && BSP_FEATURE_CANFD_NUM_INSTANCES > 1
+ .fifo_select_flags = CANFD_RX_FIFO_0
+#else
.fifo_select_flags = CANFD_RX_FIFO_1
+#endif
}
},
};
+#endif
#endif
+#ifndef RA_CAN_USING_DYNAMIC_CANFD_TIMING
static rt_uint32_t get_can_baud_index(rt_uint32_t baud)
{
rt_uint32_t len, index;
@@ -112,6 +129,167 @@ static rt_uint32_t get_can_baud_index(rt_uint32_t baud)
return 0; /* default baud is CAN1MBaud */
}
+#endif
+
+#ifdef RA_CAN_USING_DYNAMIC_CANFD_TIMING
+static rt_uint32_t ra_canfd_clock_divisor_get(void)
+{
+#if BSP_CFG_CANFDCLK_DIV == BSP_CLOCKS_CANFD_CLOCK_DIV_1
+ return 1;
+#elif BSP_CFG_CANFDCLK_DIV == BSP_CLOCKS_CANFD_CLOCK_DIV_2
+ return 2;
+#elif defined(BSP_CLOCKS_CANFD_CLOCK_DIV_3) && \
+ BSP_CFG_CANFDCLK_DIV == BSP_CLOCKS_CANFD_CLOCK_DIV_3
+ return 3;
+#elif BSP_CFG_CANFDCLK_DIV == BSP_CLOCKS_CANFD_CLOCK_DIV_4
+ return 4;
+#elif defined(BSP_CLOCKS_CANFD_CLOCK_DIV_5) && \
+ BSP_CFG_CANFDCLK_DIV == BSP_CLOCKS_CANFD_CLOCK_DIV_5
+ return 5;
+#elif BSP_CFG_CANFDCLK_DIV == BSP_CLOCKS_CANFD_CLOCK_DIV_6
+ return 6;
+#elif BSP_CFG_CANFDCLK_DIV == BSP_CLOCKS_CANFD_CLOCK_DIV_8
+ return 8;
+#elif defined(BSP_CLOCKS_CANFD_CLOCK_DIV_10) && \
+ BSP_CFG_CANFDCLK_DIV == BSP_CLOCKS_CANFD_CLOCK_DIV_10
+ return 10;
+#elif defined(BSP_CLOCKS_CANFD_CLOCK_DIV_16) && \
+ BSP_CFG_CANFDCLK_DIV == BSP_CLOCKS_CANFD_CLOCK_DIV_16
+ return 16;
+#elif defined(BSP_CLOCKS_CANFD_CLOCK_DIV_32) && \
+ BSP_CFG_CANFDCLK_DIV == BSP_CLOCKS_CANFD_CLOCK_DIV_32
+ return 32;
+#else
+ return 0;
+#endif
+}
+
+static rt_uint32_t ra_canfd_clock_hz_get(void)
+{
+ rt_uint32_t source_clock;
+
+ source_clock = R_BSP_SourceClockHzGet((fsp_priv_source_clock_t)BSP_CFG_CANFDCLK_SOURCE);
+#if BSP_CFG_CANFDCLK_SOURCE == BSP_CLOCKS_SOURCE_CLOCK_MAIN_OSC
+ return source_clock;
+#else
+ rt_uint32_t divisor = ra_canfd_clock_divisor_get();
+
+ return divisor == 0 ? 0 : source_clock / divisor;
+#endif
+}
+
+static rt_err_t ra_canfd_timing_calculate(can_bit_timing_cfg_t *timing,
+ rt_uint32_t clock_hz,
+ rt_uint32_t baud,
+ rt_bool_t data_phase)
+{
+ rt_uint32_t max_prescaler = data_phase ? 256 : 1024;
+ rt_uint32_t max_time_segment_1 = data_phase ? 32 : 256;
+ rt_uint32_t max_time_segment_2 = data_phase ? 16 : 128;
+ rt_uint32_t prescaler;
+
+ if (timing == RT_NULL || clock_hz == 0 || baud == 0)
+ {
+ return -RT_EINVAL;
+ }
+
+ for (prescaler = 1; prescaler <= max_prescaler; prescaler++)
+ {
+ rt_uint32_t denominator = baud * prescaler;
+ rt_uint32_t total_tq;
+ rt_uint32_t sample_tq;
+ rt_uint32_t time_segment_1;
+ rt_uint32_t time_segment_2;
+
+ if (denominator == 0 || clock_hz % denominator != 0)
+ {
+ continue;
+ }
+
+ total_tq = clock_hz / denominator;
+ if (total_tq < 8 ||
+ total_tq > max_time_segment_1 + max_time_segment_2 + 1)
+ {
+ continue;
+ }
+
+ sample_tq = (total_tq * 3) / 4;
+ time_segment_1 = sample_tq - 1;
+ time_segment_2 = total_tq - sample_tq;
+ if (time_segment_1 > max_time_segment_1 ||
+ time_segment_2 > max_time_segment_2 ||
+ time_segment_1 <= time_segment_2 || time_segment_2 == 0)
+ {
+ continue;
+ }
+
+ timing->baud_rate_prescaler = prescaler;
+ timing->time_segment_1 = time_segment_1;
+ timing->time_segment_2 = time_segment_2;
+ timing->synchronization_jump_width = time_segment_2 < 4 ? time_segment_2 : 4;
+ return RT_EOK;
+ }
+
+ return -RT_EINVAL;
+}
+#endif
+
+static rt_err_t ra_can_apply_baud(struct ra_can *can, rt_uint32_t baud)
+{
+ can_bit_timing_cfg_t *timing = can->config->p_cfg->p_bit_timing;
+
+#ifdef RA_CAN_USING_DYNAMIC_CANFD_TIMING
+ rt_uint32_t clock_hz = ra_canfd_clock_hz_get();
+
+ return ra_canfd_timing_calculate(timing, clock_hz, baud, RT_FALSE);
+#else
+ rt_uint32_t index = get_can_baud_index(baud);
+
+ timing->baud_rate_prescaler = can_baud_rate_tab[index].prescaler;
+ timing->synchronization_jump_width = can_baud_rate_tab[index].sjw;
+ timing->time_segment_1 = can_baud_rate_tab[index].ts1;
+ timing->time_segment_2 = can_baud_rate_tab[index].ts2;
+ return RT_EOK;
+#endif
+}
+
+static void ra_can_irq_control(IRQn_Type irq, rt_bool_t enable)
+{
+ if (irq < 0)
+ {
+ return;
+ }
+
+ if (enable)
+ {
+ R_BSP_IrqEnable(irq);
+ }
+ else
+ {
+ R_BSP_IrqDisable(irq);
+ R_BSP_IrqStatusClear(irq);
+ }
+}
+
+#if defined(BSP_USING_CANFD) && defined(VECTOR_NUMBER_CAN_RXF)
+static rt_bool_t ra_can_other_rx_irq_enabled(struct ra_can *can)
+{
+ rt_size_t index;
+
+ for (index = 0; index < sizeof(can_obj) / sizeof(can_obj[0]); index++)
+ {
+ struct rt_can_device *can_dev = &can_obj[index].can_dev;
+
+ if (&can_obj[index] != can && can_dev->can_rx != RT_NULL &&
+ (can_dev->parent.open_flag & RT_DEVICE_FLAG_INT_RX))
+ {
+ return RT_TRUE;
+ }
+ }
+
+ return RT_FALSE;
+}
+#endif
static void ra_can_get_config(void)
{
@@ -132,6 +310,7 @@ static void ra_can_get_config(void)
rt_err_t ra_can_configure(struct rt_can_device *can_dev, struct can_configure *cfg)
{
struct ra_can *can;
+ rt_err_t result;
RT_ASSERT(can_dev != RT_NULL);
RT_ASSERT(cfg != RT_NULL);
@@ -140,11 +319,48 @@ rt_err_t ra_can_configure(struct rt_can_device *can_dev, struct can_configure *c
can = rt_container_of(can_dev, struct ra_can, can_dev);
RT_ASSERT(can != RT_NULL);
+ result = ra_can_apply_baud(can, cfg->baud_rate);
+ if (result != RT_EOK)
+ {
+ return result;
+ }
+
+#if defined(RA_CAN_USING_DYNAMIC_CANFD_TIMING) && defined(BSP_USING_CANFD)
+ if (cfg->enable_canfd)
+ {
+ canfd_extended_cfg_t *extend = (canfd_extended_cfg_t *)can->config->p_cfg->p_extend;
+
+ if (extend == RT_NULL || extend->p_data_timing == RT_NULL)
+ {
+ return -RT_EINVAL;
+ }
+
+ result = ra_canfd_timing_calculate(extend->p_data_timing,
+ ra_canfd_clock_hz_get(),
+ cfg->baud_rate_fd,
+ RT_TRUE);
+ if (result != RT_EOK)
+ {
+ return result;
+ }
+ }
+#endif
+
+ if (((can_instance_ctrl_t *)can->config->p_api_ctrl)->open != 0)
+ {
+ err = R_CAN_Close(can->config->p_api_ctrl);
+ if (FSP_SUCCESS != err)
+ {
+ return -RT_ERROR;
+ }
+ }
+
err = R_CAN_Open(can->config->p_api_ctrl, can->config->p_cfg);
if (FSP_SUCCESS != err)
{
return -RT_ERROR;
}
+ can_dev->config = *cfg;
return RT_EOK;
}
rt_err_t ra_can_control(struct rt_can_device *can_dev, int cmd, void *arg)
@@ -156,8 +372,31 @@ rt_err_t ra_can_control(struct rt_can_device *can_dev, int cmd, void *arg)
can = rt_container_of(can_dev, struct ra_can, can_dev);
switch (cmd)
{
+ case RT_DEVICE_CTRL_SET_INT:
case RT_DEVICE_CTRL_CLR_INT:
- R_BSP_IrqStatusClear((IRQn_Type)arg);
+ argval = (rt_uint32_t)(rt_ubase_t)arg;
+ if (argval == RT_DEVICE_FLAG_INT_RX)
+ {
+ ra_can_irq_control(can->config->p_cfg->rx_irq, cmd == RT_DEVICE_CTRL_SET_INT);
+#if defined(BSP_USING_CANFD) && defined(VECTOR_NUMBER_CAN_RXF)
+ if (cmd == RT_DEVICE_CTRL_SET_INT || !ra_can_other_rx_irq_enabled(can))
+ {
+ ra_can_irq_control(VECTOR_NUMBER_CAN_RXF, cmd == RT_DEVICE_CTRL_SET_INT);
+ }
+#endif
+ }
+ else if (argval == RT_DEVICE_FLAG_INT_TX)
+ {
+ ra_can_irq_control(can->config->p_cfg->tx_irq, cmd == RT_DEVICE_CTRL_SET_INT);
+ }
+ else if (argval == RT_DEVICE_CAN_INT_ERR)
+ {
+ ra_can_irq_control(can->config->p_cfg->error_irq, cmd == RT_DEVICE_CTRL_SET_INT);
+ }
+ else
+ {
+ return -RT_EINVAL;
+ }
break;
case RT_CAN_CMD_SET_BAUD:
argval = (rt_uint32_t) arg;
@@ -175,13 +414,10 @@ rt_err_t ra_can_control(struct rt_can_device *can_dev, int cmd, void *arg)
}
if (argval != can->can_dev.config.baud_rate)
{
- can->can_dev.config.baud_rate = argval;
- uint32_t index = get_can_baud_index(argval);
- can->config->p_cfg->p_bit_timing->baud_rate_prescaler = can_baud_rate_tab[index].prescaler;
- can->config->p_cfg->p_bit_timing->synchronization_jump_width = can_baud_rate_tab[index].sjw;
- can->config->p_cfg->p_bit_timing->time_segment_1 = can_baud_rate_tab[index].ts1;
- can->config->p_cfg->p_bit_timing->time_segment_2 = can_baud_rate_tab[index].ts2;
- return ra_can_configure(&can->can_dev, &can->can_dev.config);
+ struct can_configure config = can->can_dev.config;
+
+ config.baud_rate = argval;
+ return ra_can_configure(&can->can_dev, &config);
}
break;
case RT_CAN_CMD_SET_MODE:
@@ -195,21 +431,35 @@ rt_err_t ra_can_control(struct rt_can_device *can_dev, int cmd, void *arg)
if (argval != can->can_dev.config.mode)
{
can_test_mode_t mode_to_set;
- can->can_dev.config.mode = argval;
+
switch (argval)
{
case RT_CAN_MODE_NORMAL:
mode_to_set = CAN_TEST_MODE_DISABLED;
+ break;
case RT_CAN_MODE_LISTEN:
mode_to_set = CAN_TEST_MODE_LISTEN;
+ break;
case RT_CAN_MODE_LOOPBACK:
mode_to_set = CAN_TEST_MODE_LOOPBACK_INTERNAL;
+ break;
+ default:
+ return -RT_EINVAL;
+ }
+ if (R_CAN_ModeTransition(can->config->p_api_ctrl,
+ ((can_instance_ctrl_t *)can->config->p_api_ctrl)->operation_mode,
+ mode_to_set) != FSP_SUCCESS)
+ {
+ return -RT_ERROR;
}
- R_CAN_ModeTransition(can->config->p_api_ctrl, ((can_instance_ctrl_t *)(can->config->p_api_ctrl))->operation_mode, mode_to_set);
+ can->can_dev.config.mode = argval;
}
break;
case RT_CAN_CMD_GET_STATUS:
- R_CAN_InfoGet(can->config->p_api_ctrl, &can_info);
+ if (R_CAN_InfoGet(can->config->p_api_ctrl, &can_info) != FSP_SUCCESS)
+ {
+ return -RT_ERROR;
+ }
can->can_dev.status.rcverrcnt = can_info.error_count_receive;
can->can_dev.status.snderrcnt = can_info.error_count_transmit;
can->can_dev.status.errcode = can_info.error_code;
@@ -220,32 +470,105 @@ rt_err_t ra_can_control(struct rt_can_device *can_dev, int cmd, void *arg)
}
return RT_EOK;
}
+
+#if defined(BSP_USING_CANFD)
+static rt_err_t ra_can_dlc_to_length(rt_uint8_t dlc, rt_uint8_t *length)
+{
+ static const rt_uint8_t dlc_to_length[] =
+ {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 12, 16, 20, 24, 32, 48, 64
+ };
+
+ if (dlc >= sizeof(dlc_to_length))
+ {
+ return -RT_EINVAL;
+ }
+
+ *length = dlc_to_length[dlc];
+ return RT_EOK;
+}
+
+static rt_err_t ra_can_length_to_dlc(rt_uint8_t length, rt_uint8_t *dlc)
+{
+ static const rt_uint8_t dlc_to_length[] =
+ {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 12, 16, 20, 24, 32, 48, 64
+ };
+ rt_uint8_t index;
+
+ for (index = 0; index < sizeof(dlc_to_length); index++)
+ {
+ if (dlc_to_length[index] == length)
+ {
+ *dlc = index;
+ return RT_EOK;
+ }
+ }
+
+ return -RT_EINVAL;
+}
+#endif
+
rt_ssize_t ra_can_sendmsg(struct rt_can_device *can_dev, const void *buf, rt_uint32_t boxno)
{
struct ra_can *can;
can_frame_t g_can_tx_frame;
struct rt_can_msg *msg_rt = (struct rt_can_msg *)buf;
+ rt_uint8_t payload_length;
RT_ASSERT(can_dev != RT_NULL);
RT_ASSERT(buf != RT_NULL);
+ rt_memset(&g_can_tx_frame, 0, sizeof(g_can_tx_frame));
g_can_tx_frame.id = msg_rt->id;
g_can_tx_frame.id_mode = msg_rt->ide;
g_can_tx_frame.type = msg_rt->rtr;
+#if defined(BSP_USING_CANFD)
+#ifdef BSP_USING_CANFD
+ if ((!msg_rt->fd_frame && (msg_rt->len > 8 || msg_rt->brs)) ||
+ (msg_rt->fd_frame && msg_rt->rtr))
+ {
+ return -RT_EINVAL;
+ }
+#else
+ if (msg_rt->len > 8)
+ {
+ return -RT_EINVAL;
+ }
+#endif
+ if (ra_can_dlc_to_length(msg_rt->len, &payload_length) != RT_EOK)
+ {
+ return -RT_EINVAL;
+ }
+ g_can_tx_frame.data_length_code = payload_length;
+#else
+ if (msg_rt->len > 8)
+ {
+ return -RT_EINVAL;
+ }
+ payload_length = msg_rt->len;
g_can_tx_frame.data_length_code = msg_rt->len;
-#if defined(BSP_USING_CANFD) && (defined(BSP_USING_CAN_RZ) || defined(BSP_USING_CAN_RA))
+#endif
+#if defined(BSP_USING_CANFD)
g_can_tx_frame.options = 0;
-#elif defined(BSP_USING_CANFD)
- g_can_tx_frame.options = CANFD_FRAME_OPTION_FD | CANFD_FRAME_OPTION_BRS;
+#ifdef BSP_USING_CANFD
+ if (msg_rt->fd_frame)
+ {
+ g_can_tx_frame.options |= CANFD_FRAME_OPTION_FD;
+ if (msg_rt->brs)
+ {
+ g_can_tx_frame.options |= CANFD_FRAME_OPTION_BRS;
+ }
+ }
+#endif
#else
g_can_tx_frame.options = 0;
#endif
- memcpy(g_can_tx_frame.data, msg_rt->data, 8);
+ memcpy(g_can_tx_frame.data, msg_rt->data, payload_length);
can = rt_container_of(can_dev, struct ra_can, can_dev);
RT_ASSERT(boxno < can->config->num_of_mailboxs);
if (R_CAN_Write(can->config->p_api_ctrl, boxno, &g_can_tx_frame) != FSP_SUCCESS)
{
- rt_exit_critical();
return -RT_ERROR;
}
return RT_EOK;
@@ -256,6 +579,8 @@ rt_ssize_t ra_can_recvmsg(struct rt_can_device *can_dev, void *buf, rt_uint32_t
struct rt_can_msg *msg_rt = (struct rt_can_msg *)buf;
can_frame_t *msg_ra;
struct ra_can *can;
+ rt_uint8_t dlc;
+ rt_uint8_t payload_length;
RT_ASSERT(can_dev != RT_NULL);
RT_ASSERT(buf != RT_NULL);
@@ -265,15 +590,37 @@ rt_ssize_t ra_can_recvmsg(struct rt_can_device *can_dev, void *buf, rt_uint32_t
return 0;
msg_ra = &can->callback_args->frame;
+ payload_length = msg_ra->data_length_code;
+ if (payload_length > sizeof(msg_rt->data))
+ {
+ return -RT_EINVAL;
+ }
+ rt_memset(msg_rt, 0, sizeof(*msg_rt));
msg_rt->id = msg_ra->id;
msg_rt->ide = msg_ra->id_mode;
msg_rt->rtr = msg_ra->type;
msg_rt->rsv = RT_NULL;
- msg_rt->len = msg_ra->data_length_code;
+#if defined(BSP_USING_CANFD)
+ if (ra_can_length_to_dlc(payload_length, &dlc) != RT_EOK)
+ {
+ return -RT_ERROR;
+ }
+ msg_rt->len = dlc;
+#else
+ msg_rt->len = payload_length;
+#endif
msg_rt->priv = boxno;
- msg_rt->hdr_index = RT_NULL;
- memcpy(msg_rt->data, msg_ra->data, msg_ra->data_length_code);
+ msg_rt->hdr_index = -1;
+#if defined(BSP_USING_CANFD)
+ msg_rt->fd_frame = (msg_ra->options & CANFD_FRAME_OPTION_FD) != 0;
+ msg_rt->brs = (msg_ra->options & CANFD_FRAME_OPTION_BRS) != 0;
+ if (boxno >= 32)
+ {
+ msg_rt->rxfifo = boxno - 32;
+ }
+#endif
+ memcpy(msg_rt->data, msg_ra->data, payload_length);
return sizeof(struct rt_can_msg);
}
const struct rt_can_ops ra_can_ops =
@@ -294,9 +641,12 @@ void can0_callback(can_callback_args_t *p_args)
rt_hw_can_isr(&can_obj[CAN0_INDEX].can_dev, RT_CAN_EVENT_TX_DONE | p_args->mailbox << 8);
break;
case CAN_EVENT_RX_COMPLETE:
- can_obj[CAN0_INDEX].callback_args = p_args;
- if (p_args->event == CAN_EVENT_RX_COMPLETE)
+ if (can_obj[CAN0_INDEX].can_dev.can_rx != RT_NULL &&
+ (can_obj[CAN0_INDEX].can_dev.parent.open_flag & RT_DEVICE_FLAG_INT_RX))
+ {
+ can_obj[CAN0_INDEX].callback_args = p_args;
rt_hw_can_isr(&can_obj[CAN0_INDEX].can_dev, RT_CAN_EVENT_RX_IND | p_args->mailbox << 8);
+ }
break;
case CAN_EVENT_TX_ABORTED:
rt_hw_can_isr(&can_obj[CAN0_INDEX].can_dev, RT_CAN_EVENT_TX_FAIL | p_args->mailbox << 8);
@@ -313,6 +663,8 @@ void can0_callback(can_callback_args_t *p_args)
{
break;
}
+ default:
+ break;
}
rt_interrupt_leave();
}
@@ -328,9 +680,12 @@ void can1_callback(can_callback_args_t *p_args)
rt_hw_can_isr(&can_obj[CAN1_INDEX].can_dev, RT_CAN_EVENT_TX_DONE | p_args->mailbox << 8);
break;
case CAN_EVENT_RX_COMPLETE:
- can_obj[CAN1_INDEX].callback_args = p_args;
- if (p_args->event == CAN_EVENT_RX_COMPLETE)
+ if (can_obj[CAN1_INDEX].can_dev.can_rx != RT_NULL &&
+ (can_obj[CAN1_INDEX].can_dev.parent.open_flag & RT_DEVICE_FLAG_INT_RX))
+ {
+ can_obj[CAN1_INDEX].callback_args = p_args;
rt_hw_can_isr(&can_obj[CAN1_INDEX].can_dev, RT_CAN_EVENT_RX_IND | p_args->mailbox << 8);
+ }
break;
case CAN_EVENT_TX_ABORTED:
rt_hw_can_isr(&can_obj[CAN1_INDEX].can_dev, RT_CAN_EVENT_TX_FAIL | p_args->mailbox << 8);
@@ -346,6 +701,8 @@ void can1_callback(can_callback_args_t *p_args)
{
break;
}
+ default:
+ break;
}
rt_interrupt_leave();
}