summaryrefslogtreecommitdiff
path: root/components/drivers/usb/usbdevice/class/cdc_vcom.c
diff options
context:
space:
mode:
authorGrissiom <[email protected]>2013-05-10 17:50:07 +0800
committerGrissiom <[email protected]>2013-05-10 17:50:07 +0800
commitd23ee75d2e36a145d62dff7bb2b738a29779c716 (patch)
treead3fafc8842430ba26274f28add91b748b2b1f0f /components/drivers/usb/usbdevice/class/cdc_vcom.c
parent5de59429fed2e0b8d55e6e705777ad2ecf9bef2f (diff)
cdc_vcom: send data as many as possible
The data filled into dcd_ep_write does not to be limited by MaxPacketSize.
Diffstat (limited to 'components/drivers/usb/usbdevice/class/cdc_vcom.c')
-rw-r--r--components/drivers/usb/usbdevice/class/cdc_vcom.c68
1 files 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;
- size = size > mps ? mps : size;
+ _in_sending = RT_TRUE;
- 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))