From c752d9b09510b62e4ecc76f4fd0343eeba5c1358 Mon Sep 17 00:00:00 2001 From: "qiuyiuestc@gmail.com" Date: Thu, 11 Oct 2012 17:06:30 +0000 Subject: submit the first version usb device stack. git-svn-id: https://rt-thread.googlecode.com/svn/trunk@2344 bbd45198-f89e-11dd-88c7-29a3b14d5316 --- components/drivers/usb/usbdevice/SConscript | 15 + components/drivers/usb/usbdevice/class/cdc.h | 157 +++++++ components/drivers/usb/usbdevice/class/cdc_vcom.c | 548 ++++++++++++++++++++++ components/drivers/usb/usbdevice/core/core.c | 65 ++- components/drivers/usb/usbdevice/core/usbdevice.c | 86 ++++ components/drivers/usb/usbhost/class/adk.c | 46 +- components/drivers/usb/usbhost/core/driver.c | 2 - components/drivers/usb/usbhost/core/hub.c | 6 +- components/drivers/usb/usbhost/core/usbhost.c | 56 +-- 9 files changed, 910 insertions(+), 71 deletions(-) create mode 100644 components/drivers/usb/usbdevice/SConscript create mode 100644 components/drivers/usb/usbdevice/class/cdc.h create mode 100644 components/drivers/usb/usbdevice/class/cdc_vcom.c create mode 100644 components/drivers/usb/usbdevice/core/usbdevice.c (limited to 'components/drivers/usb') diff --git a/components/drivers/usb/usbdevice/SConscript b/components/drivers/usb/usbdevice/SConscript new file mode 100644 index 0000000000..75d651f902 --- /dev/null +++ b/components/drivers/usb/usbdevice/SConscript @@ -0,0 +1,15 @@ +Import('RTT_ROOT') +from building import * + +cwd = GetCurrentDir() +src = Split(""" +core/core.c +core/usbdevice.c +class/cdc_vcom.c +""") + +CPPPATH = [cwd] + +group = DefineGroup('DeviceDrivers', src, depend = ['RT_USING_USB_DEVICE'], CPPPATH = CPPPATH) + +Return('group') diff --git a/components/drivers/usb/usbdevice/class/cdc.h b/components/drivers/usb/usbdevice/class/cdc.h new file mode 100644 index 0000000000..fa56e39659 --- /dev/null +++ b/components/drivers/usb/usbdevice/class/cdc.h @@ -0,0 +1,157 @@ +/* + * File : cdc.h + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2012, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2012-10-03 Yi Qiu first version + */ + +#define USB_CDC_PRODUCT_ID 0x5740 /* Product ID */ +#define USB_CDC_BUFSIZE 0x40 + +#define USB_CDC_CLASS_COMM 0x02 +#define USB_CDC_CLASS_DATA 0x0A + +#define USB_CDC_SUBCLASS_DLCM 0x01 +#define USB_CDC_SUBCLASS_ACM 0x02 +#define USB_CDC_SUBCLASS_TCM 0x03 +#define USB_CDC_SUBCLASS_MCCM 0x04 +#define USB_CDC_SUBCLASS_CCM 0x05 +#define USB_CDC_SUBCLASS_ETH 0x06 +#define USB_CDC_SUBCLASS_ATM 0x07 + +#define USB_CDC_PROTOCOL_V25TER 0x01 + +#define USB_CDC_PROTOCOL_I430 0x30 +#define USB_CDC_PROTOCOL_HDLC 0x31 +#define USB_CDC_PROTOCOL_TRANS 0x32 +#define USB_CDC_PROTOCOL_Q921M 0x50 +#define USB_CDC_PROTOCOL_Q921 0x51 +#define USB_CDC_PROTOCOL_Q921TM 0x52 +#define USB_CDC_PROTOCOL_V42BIS 0x90 +#define USB_CDC_PROTOCOL_Q931 0x91 +#define USB_CDC_PROTOCOL_V120 0x92 +#define USB_CDC_PROTOCOL_CAPI20 0x93 +#define USB_CDC_PROTOCOL_HOST 0xFD +#define USB_CDC_PROTOCOL_PUFD 0xFE + +#define USB_CDC_CS_INTERFACE 0x24 +#define USB_CDC_CS_ENDPOINT 0x25 + +#define USB_CDC_SCS_HEADER 0x00 +#define USB_CDC_SCS_CALL_MGMT 0x01 +#define USB_CDC_SCS_ACM 0x02 +#define USB_CDC_SCS_UNION 0x06 + +#define CDC_SEND_ENCAPSULATED_COMMAND 0x00 +#define CDC_GET_ENCAPSULATED_RESPONSE 0x01 +#define CDC_SET_COMM_FEATURE 0x02 +#define CDC_GET_COMM_FEATURE 0x03 +#define CDC_CLEAR_COMM_FEATURE 0x04 +#define CDC_SET_AUX_LINE_STATE 0x10 +#define CDC_SET_HOOK_STATE 0x11 +#define CDC_PULSE_SETUP 0x12 +#define CDC_SEND_PULSE 0x13 +#define CDC_SET_PULSE_TIME 0x14 +#define CDC_RING_AUX_JACK 0x15 +#define CDC_SET_LINE_CODING 0x20 +#define CDC_GET_LINE_CODING 0x21 +#define CDC_SET_CONTROL_LINE_STATE 0x22 +#define CDC_SEND_BREAK 0x23 +#define CDC_SET_RINGER_PARMS 0x30 +#define CDC_GET_RINGER_PARMS 0x31 +#define CDC_SET_OPERATION_PARMS 0x32 +#define CDC_GET_OPERATION_PARMS 0x33 +#define CDC_SET_LINE_PARMS 0x34 +#define CDC_GET_LINE_PARMS 0x35 +#define CDC_DIAL_DIGITS 0x36 +#define CDC_SET_UNIT_PARAMETER 0x37 +#define CDC_GET_UNIT_PARAMETER 0x38 +#define CDC_CLEAR_UNIT_PARAMETER 0x39 +#define CDC_GET_PROFILE 0x3A +#define CDC_SET_ETH_MULTICAST_FILTERS 0x40 +#define CDC_SET_ETH_POWER_MGMT_FILT 0x41 +#define CDC_GET_ETH_POWER_MGMT_FILT 0x42 +#define CDC_SET_ETH_PACKET_FILTER 0x43 +#define CDC_GET_ETH_STATISTIC 0x44 +#define CDC_SET_ATM_DATA_FORMAT 0x50 +#define CDC_GET_ATM_DEVICE_STATISTICS 0x51 +#define CDC_SET_ATM_DEFAULT_VC 0x52 +#define CDC_GET_ATM_VC_STATISTICS 0x53 + +#pragma pack(1) + +struct ucdc_header_descriptor +{ + rt_uint8_t length; + rt_uint8_t type; + rt_uint8_t subtype; + rt_uint16_t bcd; +}; +typedef struct ucdc_header_descriptor* ucdc_hdr_desc_t; + +struct ucdc_acm_descriptor +{ + rt_uint8_t length; + rt_uint8_t type; + rt_uint8_t subtype; + rt_uint8_t capabilties; +}; +typedef struct ucdc_acm_descriptor* ucdc_acm_desc_t; + +struct ucdc_call_mgmt_descriptor +{ + rt_uint8_t length; + rt_uint8_t type; + rt_uint8_t subtype; + rt_uint8_t capabilties; + rt_uint8_t data_interface; +}; +typedef struct ucdc_call_mgmt_descriptor* ucdc_call_mgmt_desc_t; + +struct ucdc_union_descriptor +{ + rt_uint8_t length; + rt_uint8_t type; + rt_uint8_t subtype; + rt_uint8_t master_interface; + rt_uint8_t slave_interface0; +}; +typedef struct ucdc_union_descriptor* ucdc_union_desc_t; + +struct ucdc_comm_descriptor +{ + struct uinterface_descriptor intf_desc; + struct ucdc_header_descriptor hdr_desc; + struct ucdc_call_mgmt_descriptor call_mgmt_desc; + struct ucdc_acm_descriptor acm_desc; + struct ucdc_union_descriptor union_desc; + struct uendpoint_descriptor ep_desc; +}; +typedef struct ucdc_comm_descriptor* ucdc_comm_desc_t; + +struct ucdc_data_descriptor +{ + struct uinterface_descriptor intf_desc; + struct uendpoint_descriptor ep_out_desc; + struct uendpoint_descriptor ep_in_desc; +}; +typedef struct ucdc_data_descriptor* ucdc_data_desc_t; + +struct ucdc_line_coding +{ + rt_uint32_t dwDTERate; + rt_uint8_t bCharFormat; + rt_uint8_t bParityType; + rt_uint8_t bDataBits; +}; +typedef struct ucdc_line_coding* ucdc_line_coding_t; + +#pragma pack() + diff --git a/components/drivers/usb/usbdevice/class/cdc_vcom.c b/components/drivers/usb/usbdevice/class/cdc_vcom.c new file mode 100644 index 0000000000..c3f1d992cf --- /dev/null +++ b/components/drivers/usb/usbdevice/class/cdc_vcom.c @@ -0,0 +1,548 @@ +/* + * File : cdc_vcom.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2012, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2012-10-02 Yi Qiu first version + */ + +#include +#include +#include "cdc.h" + +static uclass_t cdc; +static uep_t ep_in, ep_out, ep_cmd; + +#define CDC_RX_BUFSIZE 64 +#define CDC_TX_BUFSIZE 2048 +static rt_uint8_t rx_pool[CDC_RX_BUFSIZE]; +static rt_uint8_t tx_pool[CDC_TX_BUFSIZE]; +static struct rt_ringbuffer rx_ringbuffer; +static struct rt_ringbuffer tx_ringbuffer; +static struct rt_serial_device vcom_serial; +static struct serial_ringbuffer vcom_int_rx; +static rt_bool_t vcom_connected = RT_FALSE; + +static struct udevice_descriptor dev_desc = +{ + USB_DESC_LENGTH_DEVICE, //bLength; + USB_DESC_TYPE_DEVICE, //type; + USB_BCD_VERSION, //bcdUSB; + 0x00, //bDeviceClass; + 0x00, //bDeviceSubClass; + 0x00, //bDeviceProtocol; + 0x40, //bMaxPacketSize0; + USB_VENDOR_ID, //idVendor; + USB_CDC_PRODUCT_ID, //idProduct; + USB_BCD_DEVICE, //bcdDevice; + USB_STRING_MANU_INDEX, //iManufacturer; + USB_STRING_PRODUCT_INDEX, //iProduct; + USB_STRING_SERIAL_INDEX, //iSerialNumber; + USB_DYNAMIC, //bNumConfigurations; +}; + +/* communcation interface descriptor */ +static struct ucdc_comm_descriptor comm_desc = +{ + /* Interface Descriptor */ + USB_DESC_LENGTH_INTERFACE, + USB_DESC_TYPE_INTERFACE, + USB_DYNAMIC, + 0x00, + 0x01, + USB_CDC_CLASS_COMM, + USB_CDC_SUBCLASS_ACM, + USB_CDC_PROTOCOL_V25TER, + 0x00, + /* Header Functional Descriptor */ + 0x05, + USB_CDC_CS_INTERFACE, + USB_CDC_SCS_HEADER, + 0x0110, + /* Call Management Functional Descriptor */ + 0x05, + USB_CDC_CS_INTERFACE, + USB_CDC_SCS_CALL_MGMT, + 0x00, + USB_DYNAMIC, + /* Abstract Control Management Functional Descriptor */ + 0x04, + USB_CDC_CS_INTERFACE, + USB_CDC_SCS_ACM, + 0x02, + /* Union Functional Descriptor */ + 0x05, + USB_CDC_CS_INTERFACE, + USB_CDC_SCS_UNION, + USB_DYNAMIC, + USB_DYNAMIC, + /* Endpoint Descriptor */ + USB_DESC_LENGTH_ENDPOINT, + USB_DESC_TYPE_ENDPOINT, + USB_DYNAMIC | USB_DIR_IN, + USB_EP_ATTR_INT, + 0x08, + 0xFF, +}; + +/* data interface descriptor */ +static struct ucdc_data_descriptor data_desc = +{ + /* interface descriptor */ + USB_DESC_LENGTH_INTERFACE, + USB_DESC_TYPE_INTERFACE, + USB_DYNAMIC, + 0x00, + 0x02, + USB_CDC_CLASS_DATA, + 0x00, + 0x00, + 0x00, + /* endpoint, bulk out */ + USB_DESC_LENGTH_ENDPOINT, + USB_DESC_TYPE_ENDPOINT, + USB_DYNAMIC | USB_DIR_OUT, + USB_EP_ATTR_BULK, + USB_CDC_BUFSIZE, + 0x00, + /* endpoint, bulk in */ + USB_DESC_LENGTH_ENDPOINT, + USB_DESC_TYPE_ENDPOINT, + USB_DYNAMIC | USB_DIR_IN, + USB_EP_ATTR_BULK, + USB_CDC_BUFSIZE, + 0x00, +}; + +/** + * This function will handle cdc bulk in endpoint request. + * + * @param device the usb device object. + * @param size request size. + * + * @return RT_EOK. + */ +static rt_err_t _ep_in_handler(udevice_t device, rt_size_t size) +{ + rt_uint32_t level; + rt_size_t length; + + rt_size_t mps = ep_in->ep_desc->wMaxPacketSize; + size = RT_RINGBUFFER_SIZE(&tx_ringbuffer); + if(size == 0) return RT_EOK; + + length = size > mps ? mps : size; + + level = rt_hw_interrupt_disable(); + rt_ringbuffer_get(&tx_ringbuffer, ep_in->buffer, length); + rt_hw_interrupt_enable(level); + + /* send data to host */ + dcd_ep_write(device->dcd, ep_in, ep_in->buffer, length); + + return RT_EOK; +} + +/** + * This function will handle cdc bulk out endpoint request. + * + * @param device the usb device object. + * @param size request size. + * + * @return RT_EOK. + */ +static rt_err_t _ep_out_handler(udevice_t device, rt_size_t size) +{ + rt_uint32_t level; + + RT_ASSERT(device != RT_NULL); + + /* receive data from USB VCOM */ + level = rt_hw_interrupt_disable(); + rt_ringbuffer_put(&rx_ringbuffer, ep_out->buffer, size); + rt_hw_interrupt_enable(level); + + /* notify receive data */ + rt_hw_serial_isr(&vcom_serial); + + dcd_ep_read(device->dcd, ep_out, ep_out->buffer, + ep_out->ep_desc->wMaxPacketSize); + + return RT_EOK; +} + +/** + * This function will handle cdc interrupt in endpoint request. + * + * @param device the usb device object. + * @param size request size. + * + * @return RT_EOK. + */ +static rt_err_t _ep_cmd_handler(udevice_t device, rt_size_t size) +{ + RT_ASSERT(device != RT_NULL); + + RT_DEBUG_LOG(RT_DEBUG_USB, ("_ep_cmd_handler\n")); + + return RT_EOK; +} + +/** + * This function will handle cdc_get_line_coding request. + * + * @param device the usb device object. + * @param setup the setup request. + * + * @return RT_EOK on successful. + */ +static rt_err_t _cdc_get_line_coding(udevice_t device, ureq_t setup) +{ + struct ucdc_line_coding data; + rt_uint16_t size; + + RT_ASSERT(device != RT_NULL); + RT_ASSERT(setup != RT_NULL); + + data.dwDTERate = 115200; + data.bCharFormat = 0; + data.bDataBits = 8; + data.bParityType = 0; + size = setup->length > 7 ? 7 : setup->length; + dcd_ep_write(device->dcd, 0, (void*)&data, size); + + return RT_EOK; +} + +/** + * This function will handle cdc_set_line_coding request. + * + * @param device the usb device object. + * @param setup the setup request. + * + * @return RT_EOK on successful. + */ +static rt_err_t _cdc_set_line_coding(udevice_t device, ureq_t setup) +{ + struct ucdc_line_coding data; + rt_err_t ret; + + RT_ASSERT(device != RT_NULL); + RT_ASSERT(setup != RT_NULL); + + rt_completion_init(&device->dcd->completion); + + dcd_ep_read(device->dcd, 0, (void*)&data, setup->length); + + ret = rt_completion_wait(&device->dcd->completion, 100); + if(ret != RT_EOK) + { + rt_kprintf("_cdc_set_line_coding timeout\n"); + } + + return RT_EOK; +} + +/** + * This function will handle cdc interface request. + * + * @param device the usb device object. + * @param setup the setup request. + * + * @return RT_EOK on successful. + */ +static rt_err_t _interface_handler(udevice_t device, ureq_t setup) +{ + RT_ASSERT(device != RT_NULL); + RT_ASSERT(setup != RT_NULL); + + switch(setup->request) + { + case CDC_SEND_ENCAPSULATED_COMMAND: + break; + case CDC_GET_ENCAPSULATED_RESPONSE: + break; + case CDC_SET_COMM_FEATURE: + break; + case CDC_GET_COMM_FEATURE: + break; + case CDC_CLEAR_COMM_FEATURE: + break; + case CDC_SET_LINE_CODING: + _cdc_set_line_coding(device, setup); + vcom_connected = RT_TRUE; + break; + case CDC_GET_LINE_CODING: + _cdc_get_line_coding(device, setup); + break; + case CDC_SET_CONTROL_LINE_STATE: + rt_device_control((rt_device_t)device->dcd, CONTROL_SEND_STATUS, RT_NULL); + break; + case CDC_SEND_BREAK: + break; + default: + rt_kprintf("unknown cdc request\n",setup->request_type); + return -RT_ERROR; + } + + return RT_EOK; +} + +/** + * This function will run cdc class, it will be called on handle set configuration request. + * + * @param device the usb device object. + * + * @return RT_EOK on successful. + */ +static rt_err_t _class_run(udevice_t device) +{ + RT_ASSERT(device != RT_NULL); + + RT_DEBUG_LOG(RT_DEBUG_USB, ("cdc class run\n")); + + dcd_ep_read(device->dcd, ep_out, ep_out->buffer, + ep_out->ep_desc->wMaxPacketSize); + + return RT_EOK; +} + +/** + * This function will stop cdc class, it will be called on handle set configuration request. + * + * @param device the usb device object. + * + * @return RT_EOK on successful. + */ +static rt_err_t _class_stop(udevice_t device) +{ + RT_ASSERT(device != RT_NULL); + + RT_DEBUG_LOG(RT_DEBUG_USB, ("cdc class stop\n")); + + return RT_EOK; +} + +/** + * This function will handle system sof event. + * + * @param device the usb device object. + * + * @return RT_EOK on successful. + */ +rt_err_t _class_sof_handler(udevice_t device) +{ + rt_uint32_t level; + rt_size_t size; + static rt_uint32_t frame_count = 0; + + if(vcom_connected != RT_TRUE) return; + + if (frame_count ++ == 5) + { + rt_size_t mps = ep_in->ep_desc->wMaxPacketSize; + + /* reset the frame counter */ + frame_count = 0; + + size = RT_RINGBUFFER_SIZE(&tx_ringbuffer); + if(size == 0) return; + + size = size > mps ? mps : size; + + level = rt_hw_interrupt_disable(); + rt_ringbuffer_get(&tx_ringbuffer, ep_in->buffer, size); + rt_hw_interrupt_enable(level); + + /* send data to host */ + dcd_ep_write(device->dcd, ep_in, ep_in->buffer, size); + } +} + +static struct uclass_ops ops = +{ + _class_run, + _class_stop, + _class_sof_handler, +}; + +/** + * This function will configure cdc descriptor. + * + * @param comm the communcation interface number. + * @param data the data interface number. + * + * @return RT_EOK on successful. + */ +static rt_err_t _cdc_descriptor_config(rt_uint8_t comm, rt_uint8_t data) +{ + comm_desc.call_mgmt_desc.data_interface = data; + comm_desc.union_desc.master_interface = comm; + comm_desc.union_desc.slave_interface0 = data; + + return RT_EOK; +} + +/** + * This function will create a cdc class instance. + * + * @param device the usb device object. + * + * @return RT_EOK on successful. + */ +uclass_t rt_usbd_class_cdc_create(udevice_t device) +{ + uintf_t intf_comm, intf_data; + ualtsetting_t comm_setting, data_setting; + + /* parameter check */ + RT_ASSERT(device != RT_NULL); + + /* create a cdc class */ + cdc = rt_usbd_class_create(device, &dev_desc, &ops); + + /* create a cdc communication interface and a cdc data interface */ + intf_comm = rt_usbd_interface_create(device, _interface_handler); + intf_data = rt_usbd_interface_create(device, _interface_handler); + + /* create a communication alternate setting and a data alternate setting */ + comm_setting = rt_usbd_altsetting_create(&comm_desc.intf_desc, + sizeof(struct ucdc_comm_descriptor)); + data_setting = rt_usbd_altsetting_create(&data_desc.intf_desc, + sizeof(struct ucdc_data_descriptor)); + + /* configure the cdc interface descriptor */ + _cdc_descriptor_config(intf_comm->intf_num, intf_data->intf_num); + + /* create a bulk in and a bulk endpoint */ + ep_out = rt_usbd_endpoint_create(&data_desc.ep_out_desc, _ep_out_handler); + ep_in = rt_usbd_endpoint_create(&data_desc.ep_in_desc, _ep_in_handler); + + /* add the bulk out and bulk in endpoints to the data alternate setting */ + rt_usbd_altsetting_add_endpoint(data_setting, ep_in); + rt_usbd_altsetting_add_endpoint(data_setting, ep_out); + + /* add the data alternate setting to the data interface + then set default setting of the interface */ + rt_usbd_interface_add_altsetting(intf_data, data_setting); + rt_usbd_set_altsetting(intf_data, 0); + + /* add the cdc data interface to cdc class */ + rt_usbd_class_add_interface(cdc, intf_data); + + /* create a command endpoint */ + ep_cmd = rt_usbd_endpoint_create(&comm_desc.ep_desc, _ep_cmd_handler); + + /* add the command endpoint to the cdc communication interface */ + rt_usbd_altsetting_add_endpoint(comm_setting, ep_cmd); + + /* add the communication alternate setting to the communication interface, + then set default setting of the interface */ + rt_usbd_interface_add_altsetting(intf_comm, comm_setting); + rt_usbd_set_altsetting(intf_comm, 0); + + /* add the communication interface to the cdc class */ + rt_usbd_class_add_interface(cdc, intf_comm); + + return cdc; +} + +/** +* UART device in RT-Thread +*/ +static rt_err_t _vcom_configure(struct rt_serial_device *serial, + struct serial_configure *cfg) +{ + return RT_EOK; +} + +static rt_err_t _vcom_control(struct rt_serial_device *serial, + int cmd, void *arg) +{ + switch (cmd) + { + case RT_DEVICE_CTRL_CLR_INT: + /* disable rx irq */ + break; + case RT_DEVICE_CTRL_SET_INT: + /* enable rx irq */ + break; + } + + return RT_EOK; +} + +static int _vcom_putc(struct rt_serial_device *serial, char c) +{ + rt_uint32_t level; + + if (vcom_connected != RT_TRUE) return 0; + + level = rt_hw_interrupt_disable(); + if (RT_RINGBUFFER_EMPTY(&tx_ringbuffer)) + { + rt_ringbuffer_putchar(&tx_ringbuffer, c); + } + rt_hw_interrupt_enable(level); + + return 1; +} + +static int _vcom_getc(struct rt_serial_device *serial) +{ + int result; + rt_uint8_t ch; + rt_uint32_t level; + + result = -1; + + level = rt_hw_interrupt_disable(); + if (RT_RINGBUFFER_SIZE(&rx_ringbuffer)) + { + rt_ringbuffer_getchar(&rx_ringbuffer, &ch); + result = ch; + } + rt_hw_interrupt_enable(level); + + return result; +} + +static const struct rt_uart_ops usb_vcom_ops = +{ + _vcom_configure, + _vcom_control, + _vcom_putc, + _vcom_getc, +}; + +void rt_usb_vcom_init(void) +{ + struct serial_configure config; + + /* initialize ring buffer */ + rt_ringbuffer_init(&rx_ringbuffer, rx_pool, CDC_RX_BUFSIZE); + rt_ringbuffer_init(&tx_ringbuffer, tx_pool, CDC_TX_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; + + vcom_serial.ops = &usb_vcom_ops; + vcom_serial.int_rx = &vcom_int_rx; + vcom_serial.config = config; + + /* register vcom device */ + rt_hw_serial_register(&vcom_serial, "vcom", + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM, + RT_NULL); +} + diff --git a/components/drivers/usb/usbdevice/core/core.c b/components/drivers/usb/usbdevice/core/core.c index 17875f18cb..7cc4ea4a0b 100644 --- a/components/drivers/usb/usbdevice/core/core.c +++ b/components/drivers/usb/usbdevice/core/core.c @@ -101,7 +101,7 @@ static rt_err_t _get_string_descriptor(struct udevice* device, ureq_t setup) if(index > USB_STRING_INTERFACE_INDEX) { rt_kprintf("unknown string index\n"); - dcd_ep0_stall(device->dcd); + dcd_ep_stall(device->dcd, 0); return -RT_ERROR; } if(index == 0) @@ -158,14 +158,14 @@ static rt_err_t _get_descriptor(struct udevice* device, ureq_t setup) break; default: rt_kprintf("unknown descriptor\n"); - dcd_ep0_stall(device->dcd); + dcd_ep_stall(device->dcd, 0); break; } } else { rt_kprintf("request direction error\n"); - dcd_ep0_stall(device->dcd); + dcd_ep_stall(device->dcd, 0); } return RT_EOK; @@ -388,7 +388,7 @@ static rt_err_t _standard_request(struct udevice* device, ureq_t setup) _get_descriptor(device, setup); break; case USB_REQ_SET_DESCRIPTOR: - dcd_ep0_stall(dcd); + dcd_ep_stall(dcd, 0); break; case USB_REQ_GET_CONFIGURATION: _get_config(device, setup); @@ -398,7 +398,7 @@ static rt_err_t _standard_request(struct udevice* device, ureq_t setup) break; default: rt_kprintf("unknown device request\n"); - dcd_ep0_stall(device->dcd); + dcd_ep_stall(device->dcd, 0); break; } break; @@ -413,7 +413,7 @@ static rt_err_t _standard_request(struct udevice* device, ureq_t setup) break; default: rt_kprintf("unknown interface request\n"); - dcd_ep0_stall(device->dcd); + dcd_ep_stall(device->dcd, 0); break; } break; @@ -434,17 +434,17 @@ static rt_err_t _standard_request(struct udevice* device, ureq_t setup) break; default: rt_kprintf("unknown endpoint request\n"); - dcd_ep0_stall(device->dcd); + dcd_ep_stall(device->dcd, 0); break; } break; case USB_REQ_TYPE_OTHER: rt_kprintf("unknown other type request\n"); - dcd_ep0_stall(device->dcd); + dcd_ep_stall(device->dcd, 0); break; default: rt_kprintf("unknown type request\n"); - dcd_ep0_stall(device->dcd); + dcd_ep_stall(device->dcd, 0); break; } @@ -470,7 +470,7 @@ static rt_err_t _class_request(udevice_t device, ureq_t setup) /* verify request value */ if(setup->index > device->curr_cfg->cfg_desc.bNumInterfaces) { - dcd_ep0_stall(device->dcd); + dcd_ep_stall(device->dcd, 0); return -RT_ERROR; } @@ -484,7 +484,7 @@ static rt_err_t _class_request(udevice_t device, ureq_t setup) break; default: rt_kprintf("unknown class request type\n"); - dcd_ep0_stall(device->dcd); + dcd_ep_stall(device->dcd, 0); break; } @@ -526,13 +526,39 @@ static rt_err_t _setup_request(udevice_t device, ureq_t setup) break; default: rt_kprintf("unknown setup request type\n"); - dcd_ep0_stall(device->dcd); + dcd_ep_stall(device->dcd, 0); return -RT_ERROR; } return RT_EOK; } +/** + * This function will notity sof event to all of class. + * + * @param device the usb device object. + * + * @return RT_EOK. + */ +rt_err_t _sof_notify(udevice_t device) +{ + struct rt_list_node *i; + uclass_t cls; + + RT_ASSERT(device != RT_NULL); + + /* to notity every class that sof event comes */ + for (i=device->curr_cfg->cls_list.next; + i!=&device->curr_cfg->cls_list; i=i->next) + { + cls = (uclass_t)rt_list_entry(i, struct uclass, list); + if(cls->ops->sof_handler != RT_NULL) + cls->ops->sof_handler(device); + } + + return RT_EOK; +} + /** * This function will create an usb device object. * @@ -797,8 +823,6 @@ udevice_t rt_usbd_find_device(udcd_t dcd) { struct rt_list_node* node; udevice_t device; - - RT_DEBUG_LOG(RT_DEBUG_USB, ("rt_usbd_find_device\n")); /* parameter check */ RT_ASSERT(dcd != RT_NULL); @@ -1180,15 +1204,13 @@ static void rt_usbd_thread_entry(void* parameter) /* receive message */ if(rt_mq_recv(usb_mq, &msg, sizeof(struct udev_msg), RT_WAITING_FOREVER) != RT_EOK ) continue; - - //RT_DEBUG_LOG(RT_DEBUG_USB, ("msg type %d\n", msg.type)); switch (msg.type) { case USB_MSG_SETUP_NOTIFY: - device = rt_usbd_find_device(msg.content.setup_msg.dcd); + device = rt_usbd_find_device(msg.dcd); if(device != RT_NULL) - _setup_request(device, (ureq_t)msg.content.setup_msg.packet); + _setup_request(device, (ureq_t)msg.content.setup_msg.packet); else rt_kprintf("invalid usb device\n"); break; @@ -1199,6 +1221,13 @@ static void rt_usbd_thread_entry(void* parameter) else rt_kprintf("invalid endpoint\n"); break; + case USB_MSG_SOF: + device = rt_usbd_find_device(msg.dcd); + if(device != RT_NULL) + _sof_notify(device); + else + rt_kprintf("invalid usb device\n"); + break; default: break; } diff --git a/components/drivers/usb/usbdevice/core/usbdevice.c b/components/drivers/usb/usbdevice/core/usbdevice.c new file mode 100644 index 0000000000..97e370194e --- /dev/null +++ b/components/drivers/usb/usbdevice/core/usbdevice.c @@ -0,0 +1,86 @@ +/* + * File : usbdevice.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2012, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2012-10-02 Yi Qiu first version + */ + +#include +#include +#include + +#define RT_USB_DEVICE_CDC + +const static char* ustring[] = +{ + "Language", + "RT-Thread Team.", + "UDISK", + "12345678", + "Config", + "Interface", +}; + +rt_err_t rt_usb_device_init(const char* udc_name) +{ + rt_device_t udc; + udevice_t udevice; + uconfig_t cfg; + uclass_t cls; + + RT_ASSERT(udc_name != RT_NULL); + + udc = rt_device_find(udc_name); + if(udc == RT_NULL) + { + rt_kprintf("can't find usb device controller %s\n", udc_name); + return -RT_ERROR; + } + + /* create and startup usb device thread */ + rt_usbd_core_init(); + + /* create a device object */ + udevice = rt_usbd_device_create(ustring); + + /* set usb controller driver to the device */ + rt_usbd_device_set_controller(udevice, (udcd_t)udc); + + /* create a configuration object */ + cfg = rt_usbd_config_create(); + +#if defined RT_USB_DEVICE_MASS_STORAGE + /* create a mass storage class object */ + cls = rt_usbd_class_mass_storage_create(udevice); +#elif defined RT_USB_DEVICE_CDC + /* create a cdc class object */ + cls = rt_usbd_class_cdc_create(udevice); +#else + #error +#endif + + /* set device descriptor to the device */ + rt_usbd_device_set_descriptor(udevice, cls->dev_desc); + + /* add the mass storage class to the configuration */ + rt_usbd_config_add_class(cfg, cls); + + /* add the configuration to the device */ + rt_usbd_device_add_config(udevice, cfg); + + /* set default configuration to 1 */ + rt_usbd_set_config(udevice, 1); + + /* initialize usb device controller */ + rt_device_init(udc); + + return RT_EOK; +} + diff --git a/components/drivers/usb/usbhost/class/adk.c b/components/drivers/usb/usbhost/class/adk.c index 026940e832..208d70a090 100644 --- a/components/drivers/usb/usbhost/class/adk.c +++ b/components/drivers/usb/usbhost/class/adk.c @@ -19,17 +19,23 @@ #ifdef RT_USB_CLASS_ADK static struct uclass_driver adk_driver; +static const char* _adk_manufacturer = RT_NULL; +static const char* _adk_model = RT_NULL; +static const char* _adk_description = RT_NULL; +static const char* _adk_version = RT_NULL; +static const char* _adk_uri = RT_NULL; +static const char* _adk_serial = RT_NULL; rt_err_t rt_usb_adk_set_string(const char* manufacturer, const char* model, - const char* description, const char* version, const char* uri, + const char* description, const char* _version, const char* uri, const char* serial) { - adk_driver.manufacturer = manufacturer; - adk_driver.model = model; - adk_driver.description = description; - adk_driver.version = version; - adk_driver.uri = uri; - adk_driver.serial = serial; + _adk_manufacturer = manufacturer; + _adk_model = model; + _adk_description = description; + _adk_version = _version; + _adk_uri = uri; + _adk_serial = serial; return RT_EOK; } @@ -245,24 +251,24 @@ static rt_err_t rt_usb_adk_run(void* arg) } rt_usb_adk_send_string(ifinst, - ACCESSORY_STRING_MANUFACTURER, adk_driver.manufacturer); + ACCESSORY_STRING_MANUFACTURER, _adk_manufacturer); rt_usb_adk_send_string(ifinst, - ACCESSORY_STRING_MODEL, adk_driver.model); + ACCESSORY_STRING_MODEL, _adk_model); rt_usb_adk_send_string(ifinst, - ACCESSORY_STRING_DESCRIPTION, adk_driver.description); + ACCESSORY_STRING_DESCRIPTION, _adk_description); rt_usb_adk_send_string(ifinst, - ACCESSORY_STRING_VERSION, adk_driver.version); + ACCESSORY_STRING_VERSION, _adk_version); rt_usb_adk_send_string(ifinst, - ACCESSORY_STRING_URI, adk_driver.uri); + ACCESSORY_STRING_URI, _adk_uri); rt_usb_adk_send_string(ifinst, - ACCESSORY_STRING_SERIAL, adk_driver.serial); - - RT_DEBUG_LOG(RT_DEBUG_USB,("manufacturer %s\n", adk_driver.manufacturer)); - RT_DEBUG_LOG(RT_DEBUG_USB,("model %s\n", adk_driver.model)); - RT_DEBUG_LOG(RT_DEBUG_USB,("description %s\n", adk_driver.description)); - RT_DEBUG_LOG(RT_DEBUG_USB,("version %s\n", adk_driver.version)); - RT_DEBUG_LOG(RT_DEBUG_USB,("uri %s\n", adk_driver.uri)); - RT_DEBUG_LOG(RT_DEBUG_USB,("serial %s\n", adk_driver.serial)); + ACCESSORY_STRING_SERIAL, _adk_serial); + + RT_DEBUG_LOG(RT_DEBUG_USB,("manufacturer %s\n", _adk_manufacturer)); + RT_DEBUG_LOG(RT_DEBUG_USB,("model %s\n", _adk_model)); + RT_DEBUG_LOG(RT_DEBUG_USB,("description %s\n", _adk_description)); + RT_DEBUG_LOG(RT_DEBUG_USB,("version %s\n", _adk_version)); + RT_DEBUG_LOG(RT_DEBUG_USB,("uri %s\n", _adk_uri)); + RT_DEBUG_LOG(RT_DEBUG_USB,("serial %s\n", _adk_serial)); if((ret = rt_usb_adk_start(ifinst)) != RT_EOK) { diff --git a/components/drivers/usb/usbhost/core/driver.c b/components/drivers/usb/usbhost/core/driver.c index ecadd169d5..57c7eed8db 100644 --- a/components/drivers/usb/usbhost/core/driver.c +++ b/components/drivers/usb/usbhost/core/driver.c @@ -40,8 +40,6 @@ rt_err_t rt_usb_class_driver_init(void) rt_err_t rt_usb_class_driver_register(ucd_t drv) { - RT_ASSERT(drv != RT_NULL); - if (drv == RT_NULL) return -RT_ERROR; /* insert class driver into driver list */ diff --git a/components/drivers/usb/usbhost/core/hub.c b/components/drivers/usb/usbhost/core/hub.c index 1b6a0b5fe4..892094fe4a 100644 --- a/components/drivers/usb/usbhost/core/hub.c +++ b/components/drivers/usb/usbhost/core/hub.c @@ -545,10 +545,10 @@ static void rt_usb_hub_thread_entry(void* parameter) { while(1) { - struct umsg msg; + struct uhost_msg msg; /* receive message */ - if(rt_mq_recv(usb_mq, &msg, sizeof(struct umsg), RT_WAITING_FOREVER) + if(rt_mq_recv(usb_mq, &msg, sizeof(struct uhost_msg), RT_WAITING_FOREVER) != RT_EOK ) continue; RT_DEBUG_LOG(RT_DEBUG_USB, ("msg type %d\n", msg.type)); @@ -576,7 +576,7 @@ static void rt_usb_hub_thread_entry(void* parameter) * * @return the error code, RT_EOK on successfully. */ -rt_err_t rt_usb_post_event(struct umsg* msg, rt_size_t size) +rt_err_t rt_usb_post_event(struct uhost_msg* msg, rt_size_t size) { RT_ASSERT(msg != RT_NULL); diff --git a/components/drivers/usb/usbhost/core/usbhost.c b/components/drivers/usb/usbhost/core/usbhost.c index abafb196a6..0b5bd9a0d1 100644 --- a/components/drivers/usb/usbhost/core/usbhost.c +++ b/components/drivers/usb/usbhost/core/usbhost.c @@ -9,7 +9,7 @@ * * Change Logs: * Date Author Notes - * 2011-3-12 Yi Qiu first version + * 2011-12-12 Yi Qiu first version */ #include #include @@ -26,49 +26,49 @@ */ void rt_usb_host_init(void) { - ucd_t drv; + ucd_t drv; #ifdef RT_USB_CLASS_HID - uprotocal_t protocal; + uprotocal_t protocal; #endif - /* initialize usb hub thread */ - rt_usb_hub_thread(); + /* initialize usb hub thread */ + rt_usb_hub_thread(); - /* initialize class driver */ - rt_usb_class_driver_init(); + /* initialize class driver */ + rt_usb_class_driver_init(); #ifdef RT_USB_CLASS_MASS_STORAGE - /* register mass storage class driver */ - drv = rt_usb_class_driver_storage(); - rt_usb_class_driver_register(drv); + /* register mass storage class driver */ + drv = rt_usb_class_driver_storage(); + rt_usb_class_driver_register(drv); #endif #ifdef RT_USB_CLASS_HID - /* register hid class driver */ - drv = rt_usb_class_driver_hid(); - rt_usb_class_driver_register(drv); + /* register hid class driver */ + drv = rt_usb_class_driver_hid(); + rt_usb_class_driver_register(drv); -#ifdef RT_USB_HID_KEYBOARD - /* register hid keyboard protocal */ - protocal = rt_usb_hid_protocal_kbd(); - rt_usb_hid_protocal_register(protocal); +#ifdef RT_USB_HID_KEYBOARD + /* register hid keyboard protocal */ + protocal = rt_usb_hid_protocal_kbd(); + rt_usb_hid_protocal_register(protocal); #endif -#ifdef RT_USB_HID_MOUSE - /* register hid mouse protocal */ - protocal = rt_usb_hid_protocal_mouse(); - rt_usb_hid_protocal_register(protocal); -#endif +#ifdef RT_USB_HID_MOUSE + /* register hid mouse protocal */ + protocal = rt_usb_hid_protocal_mouse(); + rt_usb_hid_protocal_register(protocal); +#endif #endif #ifdef RT_USB_CLASS_ADK - /* register adk class driver */ - drv = rt_usb_class_driver_adk(); - rt_usb_class_driver_register(drv); + /* register adk class driver */ + drv = rt_usb_class_driver_adk(); + rt_usb_class_driver_register(drv); #endif - /* register hub class driver */ - drv = rt_usb_class_driver_hub(); - rt_usb_class_driver_register(drv); + /* register hub class driver */ + drv = rt_usb_class_driver_hub(); + rt_usb_class_driver_register(drv); } -- cgit v1.3.1