Skip to content

Commit

Permalink
Fixed data loss issue when USB CDC serial works in dma transmission m…
Browse files Browse the repository at this point in the history
…ode.
  • Loading branch information
weety committed Feb 3, 2019
1 parent 48aa297 commit 5293175
Showing 1 changed file with 48 additions and 48 deletions.
96 changes: 48 additions & 48 deletions components/drivers/usb/usbdevice/class/cdc_vcom.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ static struct ucdc_line_coding line_coding;
#define CDC_BULKIN_MAXSIZE (CDC_TX_BUFSIZE / 8)

#define CDC_TX_HAS_DATE 0x01
#define CDC_TX_HAS_SPACE 0x02

struct vcom
{
Expand Down Expand Up @@ -693,88 +694,86 @@ static int _vcom_getc(struct rt_serial_device *serial)

return result;
}
static rt_size_t _vcom_tx(struct rt_serial_device *serial, rt_uint8_t *buf, rt_size_t size,int direction)

static rt_size_t _vcom_rb_block_put(struct vcom *data, const rt_uint8_t *buf, rt_size_t size)
{
rt_uint32_t level;
rt_size_t put_len = 0;
rt_size_t w_ptr = 0;
rt_uint32_t res;
rt_size_t remain_size = size;

while (remain_size)
{
level = rt_hw_interrupt_disable();
put_len = rt_ringbuffer_put(&data->tx_ringbuffer, (const rt_uint8_t *)&buf[w_ptr], remain_size);
rt_hw_interrupt_enable(level);
w_ptr += put_len;
remain_size -= put_len;
if (put_len == 0)
{
rt_event_recv(&data->tx_event, CDC_TX_HAS_SPACE,
RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR,
VCOM_TX_TIMEOUT, &res);
}
else
{
rt_event_send(&data->tx_event, CDC_TX_HAS_DATE);
}
}

return size;
}

static rt_size_t _vcom_tx(struct rt_serial_device *serial, rt_uint8_t *buf, rt_size_t size,int direction)
{
struct ufunction *func;
struct vcom *data;
rt_uint32_t baksize;
rt_uint32_t send_size = 0;
rt_size_t ptr = 0;
int empty = 0;
rt_uint8_t crlf[2] = {'\r', '\n',};

func = (struct ufunction*)serial->parent.user_data;
data = (struct vcom*)func->user_data;

size = (size >= CDC_BULKIN_MAXSIZE) ? CDC_BULKIN_MAXSIZE : size;
baksize = size;

RT_ASSERT(serial != RT_NULL);
RT_ASSERT(buf != RT_NULL);

RT_DEBUG_LOG(RT_DEBUG_USB, ("%s\n",__func__));

if (data->connected)
{
size = 0;
if((serial->parent.open_flag & RT_DEVICE_FLAG_STREAM))
{
empty = 0;
while(ptr < baksize)
while(send_size < size)
{
while(ptr < baksize && buf[ptr] != '\n')
while(ptr < size && buf[ptr] != '\n')
{
ptr++;
}
if(ptr < baksize)
if(ptr < size)
{
level = rt_hw_interrupt_disable();
size += rt_ringbuffer_put_force(&data->tx_ringbuffer, (const rt_uint8_t *)&buf[size], ptr - size);
rt_hw_interrupt_enable(level);

/* no data was be ignored */
if(size == ptr)
{
level = rt_hw_interrupt_disable();
if(rt_ringbuffer_space_len(&data->tx_ringbuffer) >= 2)
{
rt_ringbuffer_put_force(&data->tx_ringbuffer, crlf, 2);
size++;
}
rt_hw_interrupt_enable(level);
}
else
{
empty = 1;
break;
}

/* ring buffer is full */
if(size == ptr)
{
empty = 1;
break;
}
send_size += _vcom_rb_block_put(data, (const rt_uint8_t *)&buf[send_size], ptr - send_size);
_vcom_rb_block_put(data, crlf, 2);
send_size++;
ptr++;
}
else if (ptr == size)
{
send_size += _vcom_rb_block_put(data, (const rt_uint8_t *)&buf[send_size], ptr - send_size);
}
else
{
break;
}
}
}

if(size < baksize && !empty)
else
{
level = rt_hw_interrupt_disable();
size += rt_ringbuffer_put_force(&data->tx_ringbuffer, (rt_uint8_t *)&buf[size], baksize - size);
rt_hw_interrupt_enable(level);
}

if(size)
{
rt_event_send(&data->tx_event, CDC_TX_HAS_DATE);
while (send_size < size)
{
send_size += _vcom_rb_block_put(data, (rt_uint8_t *)&buf[send_size], size - send_size);
}
}
}
else
Expand Down Expand Up @@ -902,6 +901,7 @@ static void vcom_tx_thread_entry(void* parameter)
#else
rt_hw_serial_isr(&data->serial,RT_SERIAL_EVENT_TX_DMADONE);
#endif
rt_event_send(&data->tx_event, CDC_TX_HAS_SPACE);
}
}

Expand Down

0 comments on commit 5293175

Please sign in to comment.