Merge pull request #515 from AubrCool/master

fix some can driver problems
This commit is contained in:
Bernard Xiong 2015-07-07 14:15:06 +08:00
commit c41751672e
2 changed files with 38 additions and 21 deletions

View File

@ -56,7 +56,6 @@ rt_inline int _can_int_rx(struct rt_can_device *can, struct rt_can_msg *data, in
{ {
int size; int size;
struct rt_can_rx_fifo *rx_fifo; struct rt_can_rx_fifo *rx_fifo;
RT_ASSERT(can != RT_NULL); RT_ASSERT(can != RT_NULL);
size = msgs; size = msgs;
@ -67,6 +66,9 @@ rt_inline int _can_int_rx(struct rt_can_device *can, struct rt_can_msg *data, in
while (msgs) while (msgs)
{ {
rt_base_t level; rt_base_t level;
#ifdef RT_CAN_USING_HDR
rt_int32_t hdr;
#endif /*RT_CAN_USING_HDR*/
struct rt_can_msg_list *listmsg = RT_NULL; struct rt_can_msg_list *listmsg = RT_NULL;
/* disable interrupt */ /* disable interrupt */
@ -189,6 +191,7 @@ rt_inline int _can_int_tx(struct rt_can_device *can, const struct rt_can_msg *da
rt_list_remove(&tx_tosnd->list); rt_list_remove(&tx_tosnd->list);
} }
rt_list_insert_before(&tx_fifo->freelist, &tx_tosnd->list); rt_list_insert_before(&tx_fifo->freelist, &tx_tosnd->list);
rt_completion_done(&(tx_fifo->completion));
rt_hw_interrupt_enable(level); rt_hw_interrupt_enable(level);
if (result == RT_CAN_SND_RESULT_OK) if (result == RT_CAN_SND_RESULT_OK)
@ -208,13 +211,6 @@ rt_inline int _can_int_tx(struct rt_can_device *can, const struct rt_can_msg *da
rt_hw_interrupt_enable(level); rt_hw_interrupt_enable(level);
break; break;
} }
level = rt_hw_interrupt_disable();
if (rt_list_isempty(&tx_fifo->freelist))
{
rt_completion_done(&(tx_fifo->completion));
}
rt_hw_interrupt_enable(level);
} }
return (size - msgs); return (size - msgs);
@ -541,12 +537,12 @@ static rt_err_t rt_can_control(struct rt_device *dev,
{ {
rt_completion_done(&(tx_fifo->completion)); rt_completion_done(&(tx_fifo->completion));
level = rt_hw_interrupt_disable();
for (i = 0; i < can->config.sndboxnumber; i++) for (i = 0; i < can->config.sndboxnumber; i++)
{ {
level = rt_hw_interrupt_disable();
rt_list_remove(&tx_fifo->buffer[i].list); rt_list_remove(&tx_fifo->buffer[i].list);
rt_hw_interrupt_enable(level);
} }
rt_hw_interrupt_enable(level);
} }
else else
{ {
@ -600,8 +596,10 @@ static rt_err_t rt_can_control(struct rt_device *dev,
level = rt_hw_interrupt_disable(); level = rt_hw_interrupt_disable();
if (!can->hdr[pitem->hdr].connected) if (!can->hdr[pitem->hdr].connected)
{ {
rt_hw_interrupt_enable(level);
rt_memcpy(&can->hdr[pitem->hdr].filter, pitem, rt_memcpy(&can->hdr[pitem->hdr].filter, pitem,
sizeof(struct rt_can_filter_item)); sizeof(struct rt_can_filter_item));
level = rt_hw_interrupt_disable();
can->hdr[pitem->hdr].connected = 1; can->hdr[pitem->hdr].connected = 1;
can->hdr[pitem->hdr].msgs = 0; can->hdr[pitem->hdr].msgs = 0;
rt_list_init(&can->hdr[pitem->hdr].list); rt_list_init(&can->hdr[pitem->hdr].list);
@ -626,16 +624,20 @@ static rt_err_t rt_can_control(struct rt_device *dev,
if (can->hdr[pitem->hdr].connected) if (can->hdr[pitem->hdr].connected)
{ {
rt_memset(&can->hdr[pitem->hdr].filter, 0,
sizeof(struct rt_can_filter_item));
can->hdr[pitem->hdr].connected = 0; can->hdr[pitem->hdr].connected = 0;
can->hdr[pitem->hdr].msgs = 0; can->hdr[pitem->hdr].msgs = 0;
if (!rt_list_isempty(&can->hdr[pitem->hdr].list)) if (!rt_list_isempty(&can->hdr[pitem->hdr].list))
{ {
rt_list_remove(can->hdr[pitem->hdr].list.next); rt_list_remove(can->hdr[pitem->hdr].list.next);
} }
rt_hw_interrupt_enable(level);
rt_memset(&can->hdr[pitem->hdr].filter, 0,
sizeof(struct rt_can_filter_item));
} }
rt_hw_interrupt_enable(level); else
{
rt_hw_interrupt_enable(level);
}
count--; count--;
pitem++; pitem++;
} }
@ -643,7 +645,11 @@ static rt_err_t rt_can_control(struct rt_device *dev,
} }
break; break;
#endif /*RT_CAN_USING_HDR*/ #endif /*RT_CAN_USING_HDR*/
#ifdef RT_CAN_USING_BUS_HOOK
case RT_CAN_CMD_SET_BUS_HOOK:
can->bus_hook = (rt_can_bus_hook) args;
break;
#endif /*RT_CAN_USING_BUS_HOOK*/
default : default :
/* control device */ /* control device */
if (can->ops->control != RT_NULL) if (can->ops->control != RT_NULL)
@ -664,15 +670,21 @@ static void cantimeout(void *arg)
rt_can_t can = (rt_can_t)arg; rt_can_t can = (rt_can_t)arg;
rt_device_control((rt_device_t)can, RT_CAN_CMD_GET_STATUS, (void *)&can->status); rt_device_control((rt_device_t)can, RT_CAN_CMD_GET_STATUS, (void *)&can->status);
if (can->timerinitflag == 1)
{
can->timerinitflag = 0xFF;
}
if (can->status_indicate.ind != RT_NULL) if (can->status_indicate.ind != RT_NULL)
{ {
can->status_indicate.ind(can, can->status_indicate.args); can->status_indicate.ind(can, can->status_indicate.args);
} }
#ifdef RT_CAN_USING_BUS_HOOK
if(can->bus_hook)
{
can->bus_hook(can);
}
#endif /*RT_CAN_USING_BUS_HOOK*/
if (can->timerinitflag == 1)
{
can->timerinitflag = 0xFF;
}
} }
/* /*
@ -697,7 +709,9 @@ rt_err_t rt_hw_can_register(struct rt_can_device *can,
can->can_rx = RT_NULL; can->can_rx = RT_NULL;
can->can_tx = RT_NULL; can->can_tx = RT_NULL;
rt_mutex_init(&(can->lock), "can", RT_IPC_FLAG_PRIO); rt_mutex_init(&(can->lock), "can", RT_IPC_FLAG_PRIO);
#ifdef RT_CAN_USING_BUS_HOOK
can->bus_hook = RT_NULL;
#endif /*RT_CAN_USING_BUS_HOOK*/
device->init = rt_can_init; device->init = rt_can_init;
device->open = rt_can_open; device->open = rt_can_open;
device->close = rt_can_close; device->close = rt_can_close;

View File

@ -139,6 +139,7 @@ struct rt_can_ops;
#define RT_CAN_CMD_SET_PRIV 0x16 #define RT_CAN_CMD_SET_PRIV 0x16
#define RT_CAN_CMD_GET_STATUS 0x17 #define RT_CAN_CMD_GET_STATUS 0x17
#define RT_CAN_CMD_SET_STATUS_IND 0x18 #define RT_CAN_CMD_SET_STATUS_IND 0x18
#define RT_CAN_CMD_SET_BUS_HOOK 0x19
#define RT_DEVICE_CAN_INT_ERR 0x1000 #define RT_DEVICE_CAN_INT_ERR 0x1000
@ -195,7 +196,7 @@ typedef struct rt_can_status_ind_type
rt_canstatus_ind ind; rt_canstatus_ind ind;
void *args; void *args;
} *rt_can_status_ind_type_t; } *rt_can_status_ind_type_t;
typedef void (*rt_can_bus_hook)(struct rt_can_device *);
struct rt_can_device struct rt_can_device
{ {
struct rt_device parent; struct rt_device parent;
@ -211,7 +212,9 @@ struct rt_can_device
#ifdef RT_CAN_USING_HDR #ifdef RT_CAN_USING_HDR
struct rt_can_hdr *hdr; struct rt_can_hdr *hdr;
#endif #endif
#ifdef RT_CAN_USING_BUS_HOOK
rt_can_bus_hook bus_hook;
#endif /*RT_CAN_USING_BUS_HOOK*/
struct rt_mutex lock; struct rt_mutex lock;
void *can_rx; void *can_rx;
void *can_tx; void *can_tx;