From 8b4aadb4db1d05ab91d0d68ff6a79362cb4a2f3d Mon Sep 17 00:00:00 2001 From: heyuanjie87 Date: Fri, 17 May 2013 20:53:05 +0800 Subject: [PATCH] add usb state --- .../drivers/include/drivers/usb_common.h | 27 ++++++++++ .../drivers/include/drivers/usb_device.h | 12 +++-- components/drivers/usb/usbdevice/core/core.c | 51 ++++++++++++++++--- 3 files changed, 79 insertions(+), 11 deletions(-) diff --git a/components/drivers/include/drivers/usb_common.h b/components/drivers/include/drivers/usb_common.h index 9b7f3873e1..d8d32d8306 100644 --- a/components/drivers/include/drivers/usb_common.h +++ b/components/drivers/include/drivers/usb_common.h @@ -207,6 +207,18 @@ extern "C" { (((rt_uint16_t)(*(((rt_uint8_t *)(x)) + 1))) << 8)) typedef void (*func_callback)(void *context); +typedef enum +{ + USB_STATE_NOTATTACHED = 0, + USB_STATE_ATTACHED, + USB_STATE_POWERED, + USB_STATE_RECONNECTING, + USB_STATE_UNAUTHENTICATED, + USB_STATE_DEFAULT, + USB_STATE_ADDRESS, + USB_STATE_CONFIGURED, + USB_STATE_SUSPENDED +}udevice_state_t; #pragma pack(1) @@ -310,6 +322,21 @@ struct uhub_descriptor }; typedef struct uhub_descriptor* uhub_desc_t; +struct uhid_descriptor +{ + rt_uint8_t bLength; + rt_uint8_t type; + rt_uint16_t bcdHID; + rt_uint8_t bCountryCode; + rt_uint8_t bNumDescriptors; + struct hid_descriptor_list + { + rt_uint8_t type; + rt_uint16_t wLength; + }Descriptor[1]; +}; +typedef struct uhid_descriptor* uhid_desc_t; + struct ureqest { rt_uint8_t request_type; diff --git a/components/drivers/include/drivers/usb_device.h b/components/drivers/include/drivers/usb_device.h index 331ec785c3..99e89b74c5 100644 --- a/components/drivers/include/drivers/usb_device.h +++ b/components/drivers/include/drivers/usb_device.h @@ -28,7 +28,7 @@ /* Product ID */ #ifdef USB_PRODUCT_ID #define _PRODUCT_ID USB_PRODUCT_ID -#else +#else #define _PRODUCT_ID 0x0001 #endif @@ -73,12 +73,12 @@ struct uendpoint rt_bool_t is_stall; }; typedef struct uendpoint* uep_t; - + struct ualtsetting { rt_list_t list; uintf_desc_t intf_desc; - void* desc; + void* desc; rt_size_t desc_size; rt_list_t ep_list; }; @@ -112,7 +112,7 @@ struct uclass struct udevice* device; udev_desc_t dev_desc; void* user_data; - + rt_list_t intf_list; }; typedef struct uclass* uclass_t; @@ -131,6 +131,7 @@ struct udevice struct udevice_descriptor dev_desc; const char** str; + udevice_state_t state; rt_list_t cfg_list; uconfig_t curr_cfg; rt_uint8_t nr_intf; @@ -170,7 +171,7 @@ udevice_t rt_usbd_device_create(void); uconfig_t rt_usbd_config_create(void); uclass_t rt_usbd_class_create(udevice_t device, udev_desc_t dev_desc, uclass_ops_t ops); -uintf_t rt_usbd_interface_create(udevice_t device, uintf_handler_t handler); +uintf_t rt_usbd_interface_create(udevice_t device, uintf_handler_t handler); uep_t rt_usbd_endpoint_create(uep_desc_t ep_desc, udep_handler_t handler); ualtsetting_t rt_usbd_altsetting_create(rt_size_t desc_size); @@ -198,6 +199,7 @@ uep_t rt_usbd_find_endpoint(udevice_t device, uclass_t* pcls, rt_uint8_t ep_addr uclass_t rt_usbd_class_mstorage_create(udevice_t device); uclass_t rt_usbd_class_cdc_create(udevice_t device); uclass_t rt_usbd_class_rndis_create(udevice_t device); +uclass_t rt_usbd_class_dap_create(udevice_t device); #ifdef RT_USB_DEVICE_COMPOSITE rt_err_t rt_usbd_class_set_iad(uclass_t cls, uiad_desc_t iad_desc); diff --git a/components/drivers/usb/usbdevice/core/core.c b/components/drivers/usb/usbdevice/core/core.c index 276d7bfc9f..0982f86cc0 100644 --- a/components/drivers/usb/usbdevice/core/core.c +++ b/components/drivers/usb/usbdevice/core/core.c @@ -199,6 +199,12 @@ static rt_err_t _get_interface(struct udevice* device, ureq_t setup) RT_DEBUG_LOG(RT_DEBUG_USB, ("_get_interface\n")); + if (device->state != USB_STATE_CONFIGURED) + { + dcd_ep_stall(device->dcd, 0); + return -RT_ERROR; + } + /* find the specified interface and its alternate setting */ intf = rt_usbd_find_interface(device, setup->index & 0xFF, RT_NULL); value = intf->curr_setting->intf_desc->bAlternateSetting; @@ -230,6 +236,12 @@ static rt_err_t _set_interface(struct udevice* device, ureq_t setup) RT_DEBUG_LOG(RT_DEBUG_USB, ("_set_interface\n")); + if (device->state != USB_STATE_CONFIGURED) + { + dcd_ep_stall(device->dcd, 0); + return -RT_ERROR; + } + /* find the specified interface */ intf = rt_usbd_find_interface(device, setup->index & 0xFF, RT_NULL); @@ -266,10 +278,16 @@ static rt_err_t _get_config(struct udevice* device, ureq_t setup) RT_ASSERT(device->curr_cfg != RT_NULL); RT_DEBUG_LOG(RT_DEBUG_USB, ("_get_config\n")); - - /* get current configuration */ - value = device->curr_cfg->cfg_desc.bConfigurationValue; - + + if (device->state == USB_STATE_CONFIGURED) + { + /* get current configuration */ + value = device->curr_cfg->cfg_desc.bConfigurationValue; + } + else + { + value = 0; + } /* write the current configuration to endpoint 0 */ dcd_ep_write(device->dcd, 0, &value, 1); @@ -298,6 +316,20 @@ static rt_err_t _set_config(struct udevice* device, ureq_t setup) RT_DEBUG_LOG(RT_DEBUG_USB, ("_set_config\n")); + if (setup->value > device->dev_desc.bNumConfigurations) + { + dcd_ep_stall(device->dcd, 0); + return -RT_ERROR; + } + + if (setup->value == 0) + { + RT_DEBUG_LOG(RT_DEBUG_USB, ("address state\n")); + device->state = USB_STATE_ADDRESS; + + goto _exit; + } + /* set current configuration */ rt_usbd_set_config(device, setup->value); cfg = device->curr_cfg; @@ -324,6 +356,9 @@ static rt_err_t _set_config(struct udevice* device, ureq_t setup) cls->ops->run(device, cls); } + device->state = USB_STATE_CONFIGURED; + +_exit: /* issue status stage */ dcd_send_status(device->dcd); @@ -348,7 +383,9 @@ static rt_err_t _set_address(struct udevice* device, ureq_t setup) /* set address in device control driver */ dcd_set_address(device->dcd, setup->value); - + + device->state = USB_STATE_ADDRESS; + /* issue status stage */ dcd_send_status(device->dcd); @@ -382,8 +419,10 @@ static rt_err_t _request_interface(struct udevice* device, ureq_t setup) ret = intf->handler(device, cls, setup); } else + { ret = -RT_ERROR; - + } + return ret; }