From d23ee75d2e36a145d62dff7bb2b738a29779c716 Mon Sep 17 00:00:00 2001 From: Grissiom Date: Fri, 10 May 2013 17:50:07 +0800 Subject: [PATCH] cdc_vcom: send data as many as possible The data filled into dcd_ep_write does not to be limited by MaxPacketSize. --- .../drivers/usb/usbdevice/class/cdc_vcom.c | 68 ++++++++++--------- 1 file changed, 35 insertions(+), 33 deletions(-) diff --git a/components/drivers/usb/usbdevice/class/cdc_vcom.c b/components/drivers/usb/usbdevice/class/cdc_vcom.c index 4cb3ec5551..60f840d293 100644 --- a/components/drivers/usb/usbdevice/class/cdc_vcom.c +++ b/components/drivers/usb/usbdevice/class/cdc_vcom.c @@ -21,7 +21,7 @@ #ifdef RT_USB_DEVICE_CDC #define CDC_RX_BUFSIZE 2048 -#define CDC_TX_BUFSIZE 1024 +#define CDC_TX_BUFSIZE 2048 static rt_uint8_t rx_rbp[CDC_RX_BUFSIZE]; static rt_uint8_t tx_rbp[CDC_TX_BUFSIZE]; static struct rt_ringbuffer rx_ringbuffer; @@ -32,9 +32,9 @@ static struct rt_serial_device vcom_serial; #define CDC_MaxPacketSize 64 ALIGN(RT_ALIGN_SIZE) -static rt_uint8_t rx_buf[CDC_MaxPacketSize]; +static rt_uint8_t rx_buf[CDC_RX_BUFSIZE]; ALIGN(RT_ALIGN_SIZE) -static rt_uint8_t tx_buf[CDC_MaxPacketSize]; +static rt_uint8_t tx_buf[CDC_TX_BUFSIZE]; static rt_bool_t vcom_connected = RT_FALSE; @@ -151,6 +151,7 @@ const static char* _ustring[] = }; static rt_bool_t _in_sending; + /** * This function will handle cdc bulk in endpoint request. * @@ -162,31 +163,33 @@ static rt_bool_t _in_sending; static rt_err_t _ep_in_handler(udevice_t device, uclass_t cls, rt_size_t size) { rt_uint32_t level; - rt_size_t length; cdc_eps_t eps; - rt_size_t mps; eps = (cdc_eps_t)cls->eps; - mps = eps->ep_in->ep_desc->wMaxPacketSize; + level = rt_hw_interrupt_disable(); size = RT_RINGBUFFER_SIZE(&tx_ringbuffer); if(size == 0) { if (_in_sending) { _in_sending = RT_FALSE; + /* don't have data right now. Send a zero-length-packet to + * terminate the transaction. + * + * FIXME: actually, this might not be the right place to send zlp. + * Only the rt_device_write could know how much data is sending. */ dcd_ep_write(device->dcd, eps->ep_in, RT_NULL, 0); } + rt_hw_interrupt_enable(level); return RT_EOK; } + _in_sending = RT_TRUE; - length = size > mps ? mps : size; - - level = rt_hw_interrupt_disable(); - rt_ringbuffer_get(&tx_ringbuffer, eps->ep_in->buffer, length); + rt_ringbuffer_get(&tx_ringbuffer, eps->ep_in->buffer, size); rt_hw_interrupt_enable(level); /* send data to host */ - dcd_ep_write(device->dcd, eps->ep_in, eps->ep_in->buffer, length); + dcd_ep_write(device->dcd, eps->ep_in, eps->ep_in->buffer, size); return RT_EOK; } @@ -391,33 +394,25 @@ static rt_err_t _class_sof_handler(udevice_t device, uclass_t cls) { rt_uint32_t level; rt_size_t size; - /*static rt_uint32_t frame_count = 0;*/ cdc_eps_t eps; - if(vcom_connected != RT_TRUE) return -RT_ERROR; + if (vcom_connected != RT_TRUE) + return -RT_ERROR; eps = (cdc_eps_t)cls->eps; - /*if (frame_count ++ == 5)*/ - { - rt_size_t mps = eps->ep_in->ep_desc->wMaxPacketSize; - /* reset the frame counter */ - /*frame_count = 0;*/ + size = RT_RINGBUFFER_SIZE(&tx_ringbuffer); + if(size == 0) + return -RT_EFULL; - size = RT_RINGBUFFER_SIZE(&tx_ringbuffer); - if(size == 0) - return -RT_EFULL; + _in_sending = RT_TRUE; - _in_sending = RT_TRUE; - size = size > mps ? mps : size; + level = rt_hw_interrupt_disable(); + rt_ringbuffer_get(&tx_ringbuffer, eps->ep_in->buffer, size); + rt_hw_interrupt_enable(level); - level = rt_hw_interrupt_disable(); - rt_ringbuffer_get(&tx_ringbuffer, eps->ep_in->buffer, size); - rt_hw_interrupt_enable(level); - - /* send data to host */ - dcd_ep_write(device->dcd, eps->ep_in, eps->ep_in->buffer, size); - } + /* send data to host */ + dcd_ep_write(device->dcd, eps->ep_in, eps->ep_in->buffer, size); return RT_EOK; } @@ -554,17 +549,24 @@ static rt_err_t _vcom_control(struct rt_serial_device *serial, static int _vcom_putc(struct rt_serial_device *serial, char c) { rt_uint32_t level; - int cnt = 0; + int cnt = 500; if (vcom_connected != RT_TRUE) return 0; - while (RT_RINGBUFFER_EMPTY(&tx_ringbuffer) == 0) + /* if the buffer is full, there is a chance that the host would pull some + * data out soon. But we cannot rely on that and if we wait to long, just + * return. */ + for (cnt = 500; + RT_RINGBUFFER_EMPTY(&tx_ringbuffer) == 0 && cnt; + cnt--) { - rt_kprintf("wait for %d\n", cnt++); + rt_kprintf("wait for %d\n", cnt); if (vcom_connected != RT_TRUE) return 0; } + if (cnt == 0) + return 0; level = rt_hw_interrupt_disable(); if (RT_RINGBUFFER_EMPTY(&tx_ringbuffer))