mirror of
https://github.com/RT-Thread/rt-thread.git
synced 2025-12-27 01:28:23 +00:00
[usb]update usb stack
This commit is contained in:
@@ -22,24 +22,31 @@
|
||||
* 2012-10-02 Yi Qiu first version
|
||||
* 2012-12-12 heyuanjie87 change endpoints and function handler
|
||||
* 2013-06-25 heyuanjie87 remove SOF mechinism
|
||||
* 2013-07-20 Yi Qiu do more test
|
||||
* 2013-07-20 Yi Qiu do more test
|
||||
* 2016-02-01 Urey Fix some error
|
||||
*/
|
||||
|
||||
#include <rthw.h>
|
||||
#include <rtthread.h>
|
||||
#include <rtservice.h>
|
||||
#include <rtdevice.h>
|
||||
#include <rthw.h>
|
||||
#include <drivers/serial.h>
|
||||
#include "drivers/usb_device.h"
|
||||
#include "cdc.h"
|
||||
|
||||
#ifdef RT_USB_DEVICE_CDC
|
||||
|
||||
#define TX_TIMEOUT 100
|
||||
#define TX_TIMEOUT 1000
|
||||
#define CDC_RX_BUFSIZE 2048
|
||||
#define CDC_MAX_PACKET_SIZE 64
|
||||
#define VCOM_DEVICE "vcom"
|
||||
|
||||
#define VCOM_TASK_STK_SIZE 2048
|
||||
|
||||
//#define VCOM_TX_USE_DMA
|
||||
|
||||
ALIGN(RT_ALIGN_SIZE)
|
||||
static rt_uint8_t vcom_thread_stack[512];
|
||||
static rt_uint8_t vcom_thread_stack[VCOM_TASK_STK_SIZE];
|
||||
static struct rt_thread vcom_thread;
|
||||
#define VCOM_MQ_MSG_SZ 16
|
||||
#define VCOM_MQ_MAX_MSG 4
|
||||
@@ -52,7 +59,7 @@ static struct ucdc_line_coding line_coding;
|
||||
|
||||
struct vcom
|
||||
{
|
||||
struct rt_serial_device serial;
|
||||
struct rt_serial_device serial;
|
||||
uep_t ep_out;
|
||||
uep_t ep_in;
|
||||
uep_t ep_cmd;
|
||||
@@ -61,7 +68,6 @@ struct vcom
|
||||
struct rt_completion wait;
|
||||
rt_uint8_t rx_rbp[CDC_RX_BUFSIZE];
|
||||
struct rt_ringbuffer rx_ringbuffer;
|
||||
struct serial_ringbuffer vcom_int_rx;
|
||||
};
|
||||
|
||||
struct vcom_tx_msg
|
||||
@@ -227,7 +233,7 @@ static rt_err_t _ep_in_handler(ufunction_t func, rt_size_t size)
|
||||
RT_ASSERT(func != RT_NULL);
|
||||
|
||||
RT_DEBUG_LOG(RT_DEBUG_USB, ("_ep_in_handler %d\n", size));
|
||||
|
||||
rt_kprintf("%s size = %d\n",__func__,size);
|
||||
data = (struct vcom*)func->user_data;
|
||||
if ((size != 0) && (size % CDC_MAX_PACKET_SIZE == 0))
|
||||
{
|
||||
@@ -276,11 +282,11 @@ static rt_err_t _ep_out_handler(ufunction_t func, rt_size_t size)
|
||||
rt_hw_interrupt_enable(level);
|
||||
|
||||
/* notify receive data */
|
||||
rt_hw_serial_isr(&data->serial);
|
||||
rt_hw_serial_isr(&data->serial,RT_SERIAL_EVENT_RX_IND);
|
||||
|
||||
data->ep_out->request.buffer = data->ep_out->buffer;
|
||||
data->ep_out->request.size = EP_MAXPACKET(data->ep_out);
|
||||
data->ep_out->request.req_type = UIO_REQUEST_READ_MOST;
|
||||
data->ep_out->request.req_type = UIO_REQUEST_READ_BEST;
|
||||
rt_usbd_io_request(func->device, data->ep_out, &data->ep_out->request);
|
||||
|
||||
return RT_EOK;
|
||||
@@ -325,7 +331,7 @@ static rt_err_t _cdc_get_line_coding(udevice_t device, ureq_t setup)
|
||||
data.bCharFormat = 0;
|
||||
data.bDataBits = 8;
|
||||
data.bParityType = 0;
|
||||
size = setup->length > 7 ? 7 : setup->length;
|
||||
size = setup->wLength > 7 ? 7 : setup->wLength;
|
||||
|
||||
rt_usbd_ep0_write(device, (void*)&data, size);
|
||||
|
||||
@@ -380,7 +386,7 @@ static rt_err_t _interface_handler(ufunction_t func, ureq_t setup)
|
||||
|
||||
data = (struct vcom*)func->user_data;
|
||||
|
||||
switch(setup->request)
|
||||
switch(setup->bRequest)
|
||||
{
|
||||
case CDC_SEND_ENCAPSULATED_COMMAND:
|
||||
break;
|
||||
@@ -435,7 +441,7 @@ static rt_err_t _function_enable(ufunction_t func)
|
||||
data->ep_out->request.buffer = data->ep_out->buffer;
|
||||
data->ep_out->request.size = EP_MAXPACKET(data->ep_out);
|
||||
|
||||
data->ep_out->request.req_type = UIO_REQUEST_READ_MOST;
|
||||
data->ep_out->request.req_type = UIO_REQUEST_READ_BEST;
|
||||
rt_usbd_io_request(func->device, data->ep_out, &data->ep_out->request);
|
||||
|
||||
return RT_EOK;
|
||||
@@ -630,69 +636,111 @@ static int _vcom_getc(struct rt_serial_device *serial)
|
||||
return result;
|
||||
}
|
||||
|
||||
static rt_size_t _vcom_tx(struct rt_serial_device *serial,
|
||||
const char *buf, rt_size_t size)
|
||||
#ifdef VCOM_TX_USE_DMA
|
||||
static rt_size_t _vcom_tx(struct rt_serial_device *serial, const char *buf, rt_size_t size,int direction)
|
||||
{
|
||||
struct vcom_tx_msg msg;
|
||||
static struct vcom_tx_msg msg;
|
||||
|
||||
RT_ASSERT(serial != RT_NULL);
|
||||
RT_ASSERT(buf != RT_NULL);
|
||||
|
||||
msg.buf = buf;
|
||||
msg.serial = serial;
|
||||
msg.size = size;
|
||||
rt_kprintf("%s\n",__func__);
|
||||
|
||||
if (rt_mq_send(&vcom_tx_thread_mq, (void*)&msg,
|
||||
sizeof(struct vcom_tx_msg)) != RT_EOK)
|
||||
msg.buf = buf;
|
||||
msg.serial = serial;
|
||||
msg.size = size;
|
||||
|
||||
if (rt_mq_send(&vcom_tx_thread_mq, (void*)&msg, sizeof(struct vcom_tx_msg)) != RT_EOK)
|
||||
{
|
||||
rt_kprintf("vcom send msg fail\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
return size;
|
||||
}
|
||||
#else
|
||||
static int _vcom_putc(struct rt_serial_device *serial, char c)
|
||||
{
|
||||
static struct vcom_tx_msg msg;
|
||||
|
||||
RT_ASSERT(serial != RT_NULL);
|
||||
|
||||
msg.buf = (void *)((rt_uint32_t)c);
|
||||
msg.serial = serial;
|
||||
msg.size = 1;
|
||||
if (rt_mq_send(&vcom_tx_thread_mq, (void*)&msg, sizeof(struct vcom_tx_msg)) != RT_EOK)
|
||||
{
|
||||
// rt_kprintf("vcom send msg fail\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
static const struct rt_uart_ops usb_vcom_ops =
|
||||
{
|
||||
_vcom_configure,
|
||||
_vcom_control,
|
||||
#ifndef VCOM_TX_USE_DMA
|
||||
_vcom_putc,
|
||||
_vcom_getc,
|
||||
RT_NULL
|
||||
#else
|
||||
RT_NULL,
|
||||
_vcom_getc,
|
||||
RT_NULL,
|
||||
//_vcom_tx,
|
||||
_vcom_tx
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
/* Vcom Tx Thread */
|
||||
static void vcom_tx_thread_entry(void* parameter)
|
||||
{
|
||||
struct vcom_tx_msg msg;
|
||||
|
||||
rt_uint8_t ch;
|
||||
while (1)
|
||||
{
|
||||
if (rt_mq_recv(&vcom_tx_thread_mq, (void*)&msg,
|
||||
sizeof(struct vcom_tx_msg), RT_WAITING_FOREVER) == RT_EOK)
|
||||
if (rt_mq_recv(&vcom_tx_thread_mq, (void*)&msg, sizeof(struct vcom_tx_msg), RT_WAITING_FOREVER) == RT_EOK)
|
||||
{
|
||||
struct ufunction *func;
|
||||
struct vcom *data;
|
||||
|
||||
func = (struct ufunction*)msg.serial->parent.user_data;
|
||||
data = (struct vcom*)func->user_data;
|
||||
|
||||
if (!data->connected)
|
||||
{
|
||||
/* drop msg */
|
||||
#ifndef VCOM_TX_USE_DMA
|
||||
rt_hw_serial_isr(&data->serial,RT_SERIAL_EVENT_TX_DONE);
|
||||
#else
|
||||
rt_hw_serial_isr(&data->serial,RT_SERIAL_EVENT_TX_DMADONE);
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
|
||||
rt_completion_init(&data->wait);
|
||||
#ifndef VCOM_TX_USE_DMA
|
||||
ch = (rt_uint8_t)((rt_uint32_t)msg.buf);
|
||||
data->ep_in->request.buffer = (rt_uint8_t*)&ch;
|
||||
#else
|
||||
data->ep_in->request.buffer = (rt_uint8_t*)msg.buf;
|
||||
#endif
|
||||
data->ep_in->request.size = msg.size;
|
||||
data->ep_in->request.req_type = UIO_REQUEST_WRITE;
|
||||
|
||||
data->ep_in->request.buffer = (void*)msg.buf;
|
||||
data->ep_in->request.size = msg.size;
|
||||
data->ep_in->request.req_type = UIO_REQUEST_WRITE;
|
||||
rt_usbd_io_request(func->device, data->ep_in, &data->ep_in->request);
|
||||
|
||||
if (rt_completion_wait(&data->wait, TX_TIMEOUT) != RT_EOK)
|
||||
{
|
||||
rt_kprintf("vcom tx timeout\n");
|
||||
}
|
||||
}
|
||||
#ifndef VCOM_TX_USE_DMA
|
||||
rt_hw_serial_isr(&data->serial,RT_SERIAL_EVENT_TX_DONE);
|
||||
#else
|
||||
rt_hw_serial_isr(&data->serial,RT_SERIAL_EVENT_TX_DMADONE);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -706,29 +754,41 @@ static void rt_usb_vcom_init(struct ufunction *func)
|
||||
/* initialize ring buffer */
|
||||
rt_ringbuffer_init(&data->rx_ringbuffer, data->rx_rbp, CDC_RX_BUFSIZE);
|
||||
|
||||
config.baud_rate = BAUD_RATE_115200;
|
||||
config.bit_order = BIT_ORDER_LSB;
|
||||
config.data_bits = DATA_BITS_8;
|
||||
config.parity = PARITY_NONE;
|
||||
config.stop_bits = STOP_BITS_1;
|
||||
config.invert = NRZ_NORMAL;
|
||||
config.baud_rate = BAUD_RATE_115200;
|
||||
config.data_bits = DATA_BITS_8;
|
||||
config.stop_bits = STOP_BITS_1;
|
||||
config.parity = PARITY_NONE;
|
||||
config.bit_order = BIT_ORDER_LSB;
|
||||
config.invert = NRZ_NORMAL;
|
||||
config.bufsz = CDC_RX_BUFSIZE;
|
||||
|
||||
data->serial.ops = &usb_vcom_ops;
|
||||
data->serial.int_rx = &data->vcom_int_rx;
|
||||
data->serial.config = config;
|
||||
data->serial.ops = &usb_vcom_ops;
|
||||
data->serial.serial_rx = RT_NULL;
|
||||
data->serial.config = config;
|
||||
|
||||
/* register vcom device */
|
||||
rt_hw_serial_register(&data->serial, VCOM_DEVICE,
|
||||
#ifndef VCOM_TX_USE_DMA
|
||||
RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_INT_TX,
|
||||
#else
|
||||
RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_DMA_TX,
|
||||
#endif
|
||||
func);
|
||||
|
||||
/* create an vcom message queue */
|
||||
rt_mq_init(&vcom_tx_thread_mq, "vcomq", vcom_tx_thread_mq_pool, VCOM_MQ_MSG_SZ,
|
||||
sizeof(vcom_tx_thread_mq_pool), RT_IPC_FLAG_FIFO);
|
||||
rt_mq_init(&vcom_tx_thread_mq,
|
||||
"vcomq",
|
||||
vcom_tx_thread_mq_pool,
|
||||
VCOM_MQ_MSG_SZ,
|
||||
sizeof(vcom_tx_thread_mq_pool),
|
||||
RT_IPC_FLAG_FIFO);
|
||||
|
||||
|
||||
/* init usb device thread */
|
||||
rt_thread_init(&vcom_thread, "vcom", vcom_tx_thread_entry, RT_NULL,
|
||||
vcom_thread_stack, 512, 8, 20);
|
||||
rt_thread_init(&vcom_thread, "vcom",
|
||||
vcom_tx_thread_entry, RT_NULL,
|
||||
vcom_thread_stack, VCOM_TASK_STK_SIZE,
|
||||
8, 20);
|
||||
result = rt_thread_startup(&vcom_thread);
|
||||
RT_ASSERT(result == RT_EOK);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user