submit the first version usb device stack.

git-svn-id: https://rt-thread.googlecode.com/svn/trunk@2344 bbd45198-f89e-11dd-88c7-29a3b14d5316
This commit is contained in:
qiuyiuestc@gmail.com
2012-10-11 17:06:30 +00:00
parent 051fd8eca9
commit c752d9b095
13 changed files with 1566 additions and 399 deletions

View File

@@ -0,0 +1,373 @@
/*
* File : usb_common.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-01 Yi Qiu first version
*/
#ifndef __RT_USB_COMMON_H__
#define __RT_USB_COMMON_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <rtthread.h>
#define RT_DEBUG_USB 0x00
#define USB_DYNAMIC 0x00
#define USB_CLASS_DEVICE 0x00
#define USB_CLASS_AUDIO 0x01
#define USB_CLASS_CDC 0x02
#define USB_CLASS_HID 0x03
#define USB_CLASS_PHYSICAL 0x05
#define USB_CLASS_IMAGE 0x06
#define USB_CLASS_PRINTER 0x07
#define USB_CLASS_MASS_STORAGE 0x08
#define USB_CLASS_HUB 0x09
#define USB_CLASS_CDC_DATA 0x0a
#define USB_CLASS_SMART_CARD 0x0b
#define USB_CLASS_SECURITY 0x0d
#define USB_CLASS_VIDEO 0x0e
#define USB_CLASS_HEALTHCARE 0x0f
#define USB_CLASS_DIAG_DEVICE 0xdc
#define USB_CLASS_WIRELESS 0xe0
#define USB_CLASS_MISC 0xef
#define USB_CLASS_APP_SPECIFIC 0xfe
#define USB_CLASS_VEND_SPECIFIC 0xff
#define USB_DESC_TYPE_DEVICE 0x01
#define USB_DESC_TYPE_CONFIGURATION 0x02
#define USB_DESC_TYPE_STRING 0x03
#define USB_DESC_TYPE_INTERFACE 0x04
#define USB_DESC_TYPE_ENDPOINT 0x05
#define USB_DESC_TYPE_DEVICEQUALIFIER 0x06
#define USB_DESC_TYPE_OTHERSPEED 0x07
#define USB_DESC_TYPE_HID 0x21
#define USB_DESC_TYPE_REPORT 0x22
#define USB_DESC_TYPE_PHYSICAL 0x23
#define USB_DESC_TYPE_HUB 0x29
#define USB_DESC_LENGTH_DEVICE 0x12
#define USB_DESC_LENGTH_CONFIG 0x9
#define USB_DESC_LENGTH_STRING 0x4
#define USB_DESC_LENGTH_INTERFACE 0x9
#define USB_DESC_LENGTH_ENDPOINT 0x7
#define USB_REQ_TYPE_STANDARD 0x00
#define USB_REQ_TYPE_CLASS 0x20
#define USB_REQ_TYPE_VENDOR 0x40
#define USB_REQ_TYPE_MASK 0x60
#define USB_REQ_TYPE_DIR_OUT 0x00
#define USB_REQ_TYPE_DIR_IN 0x80
#define USB_REQ_TYPE_DEVICE 0x00
#define USB_REQ_TYPE_INTERFACE 0x01
#define USB_REQ_TYPE_ENDPOINT 0x02
#define USB_REQ_TYPE_OTHER 0x03
#define USB_REQ_TYPE_RECIPIENT_MASK 0x1f
#define USB_FEATURE_ENDPOINT_HALT 0x00
#define USB_FEATURE_DEV_REMOTE_WAKEUP 0x01
#define USB_FEATURE_TEST_MODE 0x02
#define USB_REQ_GET_STATUS 0x00
#define USB_REQ_CLEAR_FEATURE 0x01
#define USB_REQ_SET_FEATURE 0x03
#define USB_REQ_SET_ADDRESS 0x05
#define USB_REQ_GET_DESCRIPTOR 0x06
#define USB_REQ_SET_DESCRIPTOR 0x07
#define USB_REQ_GET_CONFIGURATION 0x08
#define USB_REQ_SET_CONFIGURATION 0x09
#define USB_REQ_GET_INTERFACE 0x0A
#define USB_REQ_SET_INTERFACE 0x0B
#define USB_REQ_SYNCH_FRAME 0x0C
#define USB_REQ_SET_ENCRYPTION 0x0D
#define USB_REQ_GET_ENCRYPTION 0x0E
#define USB_REQ_RPIPE_ABORT 0x0E
#define USB_REQ_SET_HANDSHAKE 0x0F
#define USB_REQ_RPIPE_RESET 0x0F
#define USB_REQ_GET_HANDSHAKE 0x10
#define USB_REQ_SET_CONNECTION 0x11
#define USB_REQ_SET_SECURITY_DATA 0x12
#define USB_REQ_GET_SECURITY_DATA 0x13
#define USB_REQ_SET_WUSB_DATA 0x14
#define USB_REQ_LOOPBACK_DATA_WRITE 0x15
#define USB_REQ_LOOPBACK_DATA_READ 0x16
#define USB_REQ_SET_INTERFACE_DS 0x17
#define USB_STRING_LANGID_INDEX 0x00
#define USB_STRING_MANU_INDEX 0x01
#define USB_STRING_PRODUCT_INDEX 0x02
#define USB_STRING_SERIAL_INDEX 0x03
#define USB_STRING_CONFIG_INDEX 0x04
#define USB_STRING_INTERFACE_INDEX 0x05
#define USB_PID_OUT 0x01
#define USB_PID_ACK 0x02
#define USB_PID_DATA0 0x03
#define USB_PID_SOF 0x05
#define USB_PID_IN 0x09
#define USB_PID_NACK 0x0A
#define USB_PID_DATA1 0x0B
#define USB_PID_PRE 0x0C
#define USB_PID_SETUP 0x0D
#define USB_PID_STALL 0x0E
#define USB_EP_DESC_OUT 0x00
#define USB_EP_DESC_IN 0x80
#define USB_EP_DESC_NUM_MASK 0x0f
#define USB_EP_ATTR_CONTROL 0x00
#define USB_EP_ATTR_ISOC 0x01
#define USB_EP_ATTR_BULK 0x02
#define USB_EP_ATTR_INT 0x03
#define USB_EP_ATTR_TYPE_MASK 0x03
#define USB_EPNO_MASK 0x7f
#define USB_DIR_OUT 0x00
#define USB_DIR_IN 0x80
#define USB_DIR_MASK 0x80
#define RH_GET_PORT_STATUS 0
#define RH_SET_PORT_STATUS 1
#define RH_CLEAR_PORT_FEATURE 2
#define RH_SET_PORT_FEATURE 3
/*
* Port feature numbers
*/
#define PORT_FEAT_CONNECTION 0
#define PORT_FEAT_ENABLE 1
#define PORT_FEAT_SUSPEND 2
#define PORT_FEAT_OVER_CURRENT 3
#define PORT_FEAT_RESET 4
#define PORT_FEAT_POWER 8
#define PORT_FEAT_LOWSPEED 9
#define PORT_FEAT_HIGHSPEED 10
#define PORT_FEAT_C_CONNECTION 16
#define PORT_FEAT_C_ENABLE 17
#define PORT_FEAT_C_SUSPEND 18
#define PORT_FEAT_C_OVER_CURRENT 19
#define PORT_FEAT_C_RESET 20
/*
The HcRhPortStatus[1:NDP] register is used to control and report port events on a per-port
basis. NumberDownstreamPorts represents the number of HcRhPortStatus registers that are
implemented in hardware. The lower word is used to reflect the port status, whereas the upper
word reflects the status change bits. Some status bits are implemented with special write behavior
(see below). If a transaction (token through handshake) is in progress when a write to change
port status occurs, the resulting port status change must be postponed until the transaction
completes. Reserved bits should always be written '0'.
*/
#define PORT_CCS 0x00000001UL /* R:CurrentConnectStatus - W:ClearPortEnable */
#define PORT_PES 0x00000002UL /* R:PortEnableStatus - W:SetPortEnable */
#define PORT_PSS 0x00000004UL /* R:PortSuspendStatus - W:SetPortSuspend */
#define PORT_POCI 0x00000008UL /* R:PortOverCurrentIndicator - W:ClearSuspendStatus */
#define PORT_PRS 0x00000010UL /* R:PortResetStatus - W: SetPortReset */
#define PORT_PPS 0x00000100UL /* R:PortPowerStatus - W: SetPortPower */
#define PORT_LSDA 0x00000200UL /* R:LowSpeedDeviceAttached - W:ClearPortPower */
#define PORT_CCSC 0x00010000UL
#define PORT_PESC 0x00020000UL
#define PORT_PSSC 0x00040000UL
#define PORT_POCIC 0x00080000UL
#define PORT_PRSC 0x00100000UL
/*
*Hub Status & Hub Change bit masks
*/
#define HUB_STATUS_LOCAL_POWER 0x0001
#define HUB_STATUS_OVERCURRENT 0x0002
#define HUB_CHANGE_LOCAL_POWER 0x0001
#define HUB_CHANGE_OVERCURRENT 0x0002
#define USB_EP_ATTR(attr) (attr & USB_EP_ATTR_TYPE_MASK)
#define USB_EP_DESC_NUM(addr) (addr & USB_EP_DESC_NUM_MASK)
#define uswap_32(x) \
((((x) & 0xff000000) >> 24) | \
(((x) & 0x00ff0000) >> 8) | \
(((x) & 0x0000ff00) << 8) | \
(((x) & 0x000000ff) << 24))
#define uswap_8(x) \
(((rt_uint16_t)(*((rt_uint8_t *)(x)))) + \
(((rt_uint16_t)(*(((rt_uint8_t *)(x)) + 1))) << 8))
typedef void (*func_callback)(void *context);
#pragma pack(1)
struct usb_descriptor
{
rt_uint8_t bLength;
rt_uint8_t type;
};
typedef struct usb_descriptor* udesc_t;
struct udevice_descriptor
{
rt_uint8_t bLength;
rt_uint8_t type;
rt_uint16_t bcdUSB;
rt_uint8_t bDeviceClass;
rt_uint8_t bDeviceSubClass;
rt_uint8_t bDeviceProtocol;
rt_uint8_t bMaxPacketSize0;
rt_uint16_t idVendor;
rt_uint16_t idProduct;
rt_uint16_t bcdDevice;
rt_uint8_t iManufacturer;
rt_uint8_t iProduct;
rt_uint8_t iSerialNumber;
rt_uint8_t bNumConfigurations;
};
typedef struct udevice_descriptor* udev_desc_t;
struct uconfig_descriptor
{
rt_uint8_t bLength;
rt_uint8_t type;
rt_uint16_t wTotalLength;
rt_uint8_t bNumInterfaces;
rt_uint8_t bConfigurationValue;
rt_uint8_t iConfiguration;
rt_uint8_t bmAttributes;
rt_uint8_t MaxPower;
rt_uint8_t data[128];
};
typedef struct uconfig_descriptor* ucfg_desc_t;
struct uinterface_descriptor
{
rt_uint8_t bLength;
rt_uint8_t type;
rt_uint8_t bInterfaceNumber;
rt_uint8_t bAlternateSetting;
rt_uint8_t bNumEndpoints;
rt_uint8_t bInterfaceClass;
rt_uint8_t bInterfaceSubClass;
rt_uint8_t bInterfaceProtocol;
rt_uint8_t iInterface;
};
typedef struct uinterface_descriptor* uintf_desc_t;
/* Interface Association Descriptor (IAD) */
struct uassco_descriptor
{
rt_uint8_t bLength;
rt_uint8_t bDescriptorType;
rt_uint8_t bFirstInterface;
rt_uint8_t bInterfaceCount;
rt_uint8_t bFunctionClass;
rt_uint8_t bFunctionSubClass;
rt_uint8_t bFunctionProtocol;
rt_uint8_t iFunction;
};
typedef struct uassco_descriptor* uassco_desc_t;
struct uendpoint_descriptor
{
rt_uint8_t bLength;
rt_uint8_t type;
rt_uint8_t bEndpointAddress;
rt_uint8_t bmAttributes;
rt_uint16_t wMaxPacketSize;
rt_uint8_t bInterval;
};
typedef struct uendpoint_descriptor* uep_desc_t;
struct ustring_descriptor
{
rt_uint8_t bLength;
rt_uint8_t type;
rt_uint8_t String[64];
};
typedef struct ustring_descriptor* ustr_desc_t;
struct uhub_descriptor
{
rt_uint8_t length;
rt_uint8_t type;
rt_uint8_t num_ports;
rt_uint16_t characteristics;
rt_uint8_t pwron_to_good; /* power on to power good */
rt_uint8_t current;
rt_uint8_t removable[8];
rt_uint8_t pwr_ctl[8];
};
typedef struct uhub_descriptor* uhub_desc_t;
struct ureqest
{
rt_uint8_t request_type;
rt_uint8_t request;
rt_uint16_t value;
rt_uint16_t index;
rt_uint16_t length;
};
typedef struct ureqest* ureq_t;
struct ustorage_cbw
{
rt_uint32_t signature;
rt_uint32_t tag;
rt_uint32_t xfer_len;
rt_uint8_t dflags;
rt_uint8_t lun;
rt_uint8_t cb_len;
rt_uint8_t cb[16];
};
typedef struct ustorage_cbw* ustorage_cbw_t;
struct ustorage_csw
{
rt_uint32_t signature;
rt_uint32_t tag;
rt_uint32_t data_reside;
rt_uint8_t status;
};
typedef struct ustorage_csw* ustorage_csw_t;
#define SIZEOF_CSW 0x0d
#define SIZEOF_CBW 0x1f
#define CBWFLAGS_DIR_M 0x80
#define CBWFLAGS_DIR_IN 0x80
#define CBWFLAGS_DIR_OUT 0x00
#define SCSI_TEST_UNIT_READY 0x00
#define SCSI_REQUEST_SENSE 0x03
#define SCSI_INQUIRY_CMD 0x12
#define SCSI_ALLOW_MEDIUM_REMOVAL 0x1e
#define SCSI_MODE_SENSE_6 0x1a
#define SCSI_READ_CAPACITIES 0x23
#define SCSI_READ_CAPACITY 0x25
#define SCSI_READ_10 0x28
#define SCSI_WRITE_10 0x2a
#define SCSI_VERIFY_10 0x2f
#define CBW_SIGNATURE 0x43425355
#define CSW_SIGNATURE 0x53425355
#define CBW_TAG_VALUE 0x12345678
#define USBREQ_GET_MAX_LUN 0xfe
#define USBREQ_MASS_STORAGE_RESET 0xff
#pragma pack()
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,249 @@
/*
* File : usb_device.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-01 Yi Qiu first version
*/
#include <rtthread.h>
#include "usb_common.h"
#define CONTROL_SEND_STATUS 0x00
#define CONTROL_RECEIVE_STATUS 0x01
#define USB_VENDOR_ID 0x0483 /* Vendor ID */
#define USB_BCD_DEVICE 0x0200 /* USB Specification Release Number in Binary-Coded Decimal */
#define USB_BCD_VERSION 0x0200 /* USB 2.0 */
struct udevice;
struct uendpoint;
struct udcd_ops
{
rt_err_t (*set_address)(rt_uint8_t value);
rt_err_t (*clear_feature)(rt_uint8_t value);
rt_err_t (*set_feature)(rt_uint8_t value);
rt_err_t (*ep_alloc)(struct uendpoint* ep);
rt_err_t (*ep_free)(struct uendpoint* ep);
rt_err_t (*ep_stall)(struct uendpoint* ep);
rt_err_t (*ep_run)(struct uendpoint* ep);
rt_err_t (*ep_stop)(struct uendpoint* ep);
rt_err_t (*ep_read)(struct uendpoint* ep, void *buffer, rt_size_t size);
rt_size_t (*ep_write)(struct uendpoint* ep, void *buffer, rt_size_t size);
};
struct udcd
{
struct rt_device parent;
struct udcd_ops* ops;
struct rt_completion completion;
};
typedef struct udcd* udcd_t;
ALIGN(4)
struct uendpoint
{
rt_list_t list;
rt_uint8_t* buffer;
uep_desc_t ep_desc;
rt_err_t (*handler)(struct udevice* device, rt_size_t size);
rt_bool_t is_stall;
void* user_data;
};
typedef struct uendpoint* uep_t;
struct ualtsetting
{
rt_list_t list;
uintf_desc_t intf_desc;
rt_size_t desc_size;
rt_list_t ep_list;
};
typedef struct ualtsetting* ualtsetting_t;
struct uinterface
{
rt_list_t list;
rt_uint8_t intf_num;
ualtsetting_t curr_setting;
rt_list_t setting_list;
rt_err_t (*handler)(struct udevice* device, ureq_t setup);
};
typedef struct uinterface* uintf_t;
struct uclass_ops
{
rt_err_t (*run)(struct udevice* device);
rt_err_t (*stop)(struct udevice* device);
rt_err_t (*sof_handler)(struct udevice* device);
};
typedef struct uclass_ops* uclass_ops_t;
struct uclass
{
rt_list_t list;
uclass_ops_t ops;
struct udevice* device;
udev_desc_t dev_desc;
struct uassco_descriptor* assco;
rt_list_t intf_list;
};
typedef struct uclass* uclass_t;
struct uconfig
{
rt_list_t list;
struct uconfig_descriptor cfg_desc;
rt_list_t cls_list;
};
typedef struct uconfig* uconfig_t;
struct udevice
{
rt_list_t list;
struct udevice_descriptor dev_desc;
const char** str;
rt_list_t cfg_list;
uconfig_t curr_cfg;
rt_uint8_t nr_intf;
udcd_t dcd;
};
typedef struct udevice* udevice_t;
enum udev_msg_type
{
USB_MSG_SETUP_NOTIFY,
USB_MSG_DATA_NOTIFY,
USB_MSG_SOF,
};
typedef enum udev_msg_type udev_msg_type;
struct udev_msg
{
udev_msg_type type;
udcd_t dcd;
union
{
struct
{
rt_size_t size;
rt_uint8_t ep_addr;
}ep_msg;
struct
{
rt_uint32_t* packet;
}setup_msg;
}content;
};
typedef struct udev_msg* udev_msg_t;
udevice_t rt_usbd_device_create(const char** str);
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,
rt_err_t (*handler)(struct udevice*, ureq_t setup));
uep_t rt_usbd_endpoint_create(uep_desc_t ep_desc,
rt_err_t (*handler)(udevice_t device, rt_size_t size));
ualtsetting_t rt_usbd_altsetting_create(uintf_desc_t intf_desc, rt_size_t desc_size);
rt_err_t rt_usbd_free_device(udevice_t device);
rt_err_t rt_usbd_device_set_descriptor(udevice_t device, udev_desc_t dev_desc);
rt_err_t rt_usbd_device_add_config(udevice_t device, uconfig_t cfg);
rt_err_t rt_usbd_config_add_class(uconfig_t cfg, uclass_t cls);
rt_err_t rt_usbd_class_add_interface(uclass_t cls, uintf_t intf);
rt_err_t rt_usbd_interface_add_altsetting(uintf_t intf, ualtsetting_t setting);
rt_err_t rt_usbd_altsetting_add_endpoint(ualtsetting_t setting, uep_t ep);
rt_err_t rt_usbd_set_config(udevice_t device, rt_uint8_t value);
rt_err_t rt_usbd_set_altsetting(uintf_t intf, rt_uint8_t value);
udevice_t rt_usbd_find_device(udcd_t dcd);
uconfig_t rt_usbd_find_config(udevice_t device, rt_uint8_t value);
uintf_t rt_usbd_find_interface(udevice_t device, rt_uint8_t value);
uep_t rt_usbd_find_endpoint(udevice_t device, rt_uint8_t ep_addr);
uclass_t rt_usbd_class_mass_create(udevice_t device);
uclass_t rt_usbd_class_cdc_create(udevice_t device);
rt_inline rt_err_t dcd_set_address(udcd_t dcd, rt_uint8_t value)
{
RT_ASSERT(dcd != RT_NULL);
return dcd->ops->set_address(value);
}
rt_inline rt_err_t dcd_clear_feature(udcd_t dcd, rt_uint8_t value)
{
RT_ASSERT(dcd != RT_NULL);
return dcd->ops->clear_feature(value);
}
rt_inline rt_err_t dcd_set_feature(udcd_t dcd, rt_uint8_t value)
{
RT_ASSERT(dcd != RT_NULL);
return dcd->ops->set_feature(value);
}
rt_inline rt_err_t dcd_ep_stall(udcd_t dcd, uep_t ep)
{
RT_ASSERT(dcd != RT_NULL);
return dcd->ops->ep_stall(ep);
}
rt_inline rt_uint8_t dcd_ep_alloc(udcd_t dcd, uep_t ep)
{
RT_ASSERT(dcd != RT_NULL);
return dcd->ops->ep_alloc(ep);
}
rt_inline rt_err_t dcd_ep_free(udcd_t dcd, uep_t ep)
{
RT_ASSERT(dcd != RT_NULL);
return dcd->ops->ep_free(ep);
}
rt_inline rt_err_t dcd_ep_run(udcd_t dcd, uep_t ep)
{
RT_ASSERT(dcd != RT_NULL);
return dcd->ops->ep_run(ep);
}
rt_inline rt_err_t dcd_ep_stop(udcd_t dcd, uep_t ep)
{
RT_ASSERT(dcd != RT_NULL);
return dcd->ops->ep_stop(ep);
}
rt_inline rt_err_t dcd_ep_read(udcd_t dcd, uep_t ep, void *buffer,
rt_size_t size)
{
RT_ASSERT(dcd != RT_NULL);
return dcd->ops->ep_read(ep, buffer, size);
}
rt_inline rt_size_t dcd_ep_write(udcd_t dcd, uep_t ep, void *buffer,
rt_size_t size)
{
RT_ASSERT(dcd != RT_NULL);
return dcd->ops->ep_write(ep, buffer, size);
}

View File

@@ -20,293 +20,25 @@ extern "C" {
#endif
#include <rtthread.h>
#include "usb_common.h"
#define RT_DEBUG_USB 0x01
#define USB_MAX_DEVICE 0x20
#define USB_MAX_INTERFACE 0x08
#define USB_MAX_DEVICE 0x20
#define USB_MAX_INTERFACE 0x08
#define USB_HUB_PORT_NUM 0x04
#define SIZEOF_USB_REQUEST 0x08
#define SIZEOF_USB_REQUEST 0x08
#define UINST_STATUS_IDLE 0x00
#define UINST_STATUS_BUSY 0x01
#define UINST_STATUS_ERROR 0x02
#define UINST_STATUS_IDLE 0x00
#define UINST_STATUS_BUSY 0x01
#define UINST_STATUS_ERROR 0x02
#define UPIPE_STATUS_OK 0x00
#define UPIPE_STATUS_STALL 0x01
#define UPIPE_STATUS_ERROR 0x02
#define USB_CLASS_DEVICE 0x00
#define USB_CLASS_AUDIO 0x01
#define USB_CLASS_CDC 0x02
#define USB_CLASS_HID 0x03
#define USB_CLASS_PHYSICAL 0x05
#define USB_CLASS_IMAGE 0x06
#define USB_CLASS_PRINTER 0x07
#define USB_CLASS_MASS_STORAGE 0x08
#define USB_CLASS_HUB 0x09
#define USB_CLASS_CDC_DATA 0x0a
#define USB_CLASS_SMART_CARD 0x0b
#define USB_CLASS_SECURITY 0x0d
#define USB_CLASS_VIDEO 0x0e
#define USB_CLASS_HEALTHCARE 0x0f
#define USB_CLASS_DIAG_DEVICE 0xdc
#define USB_CLASS_WIRELESS 0xe0
#define USB_CLASS_MISC 0xef
#define USB_CLASS_APP_SPECIFIC 0xfe
#define USB_CLASS_VEND_SPECIFIC 0xff
#define USB_DESC_TYPE_DEVICE 0x01
#define USB_DESC_TYPE_CONFIGURATION 0x02
#define USB_DESC_TYPE_STRING 0x03
#define USB_DESC_TYPE_INTERFACE 0x04
#define USB_DESC_TYPE_ENDPOINT 0x05
#define USB_DESC_TYPE_DEVICEQUALIFIER 0x06
#define USB_DESC_TYPE_OTHERSPEED 0x07
#define USB_DESC_TYPE_HID 0x21
#define USB_DESC_TYPE_REPORT 0x22
#define USB_DESC_TYPE_PHYSICAL 0x23
#define USB_DESC_TYPE_HUB 0x29
#define USB_REQ_TYPE_STANDARD 0x00
#define USB_REQ_TYPE_CLASS 0x20
#define USB_REQ_TYPE_VENDOR 0x40
#define USB_REQ_TYPE_TYPE_MASK 0x60
#define USB_REQ_TYPE_DIR_OUT 0x00
#define USB_REQ_TYPE_DIR_IN 0x80
#define USB_REQ_TYPE_DEVICE 0x00
#define USB_REQ_TYPE_INTERFACE 0x01
#define USB_REQ_TYPE_ENDPOINT 0x02
#define USB_REQ_TYPE_OTHER 0x03
#define USB_REQ_TYPE_RECIPIENT_MASK 0x1f
#define USB_FEATURE_ENDPOINT_HALT 0x00
#define USB_FEATURE_DEV_REMOTE_WAKEUP 0x01
#define USB_FEATURE_TEST_MODE 0x02
#define USB_REQ_GET_STATUS 0x00
#define USB_REQ_CLEAR_FEATURE 0x01
#define USB_REQ_SET_FEATURE 0x03
#define USB_REQ_SET_ADDRESS 0x05
#define USB_REQ_GET_DESCRIPTOR 0x06
#define USB_REQ_SET_DESCRIPTOR 0x07
#define USB_REQ_GET_CONFIGURATION 0x08
#define USB_REQ_SET_CONFIGURATION 0x09
#define USB_REQ_GET_INTERFACE 0x0A
#define USB_REQ_SET_INTERFACE 0x0B
#define USB_REQ_SYNCH_FRAME 0x0C
#define USB_REQ_SET_ENCRYPTION 0x0D
#define USB_REQ_GET_ENCRYPTION 0x0E
#define USB_REQ_RPIPE_ABORT 0x0E
#define USB_REQ_SET_HANDSHAKE 0x0F
#define USB_REQ_RPIPE_RESET 0x0F
#define USB_REQ_GET_HANDSHAKE 0x10
#define USB_REQ_SET_CONNECTION 0x11
#define USB_REQ_SET_SECURITY_DATA 0x12
#define USB_REQ_GET_SECURITY_DATA 0x13
#define USB_REQ_SET_WUSB_DATA 0x14
#define USB_REQ_LOOPBACK_DATA_WRITE 0x15
#define USB_REQ_LOOPBACK_DATA_READ 0x16
#define USB_REQ_SET_INTERFACE_DS 0x17
#define USB_PID_OUT 0x01
#define USB_PID_ACK 0x02
#define USB_PID_DATA0 0x03
#define USB_PID_SOF 0x05
#define USB_PID_IN 0x09
#define USB_PID_NACK 0x0A
#define USB_PID_DATA1 0x0B
#define USB_PID_PRE 0x0C
#define USB_PID_SETUP 0x0D
#define USB_PID_STALL 0x0E
#define USB_EP_DESC_OUT 0x00
#define USB_EP_DESC_IN 0x80
#define USB_EP_DESC_NUM_MASK 0x0f
#define USB_EP_ATTR_CONTROL 0x00
#define USB_EP_ATTR_ISOC 0x01
#define USB_EP_ATTR_BULK 0x02
#define USB_EP_ATTR_INT 0x03
#define USB_EP_ATTR_TYPE_MASK 0x03
#define USB_EPNO_MASK 0x7f
#define USB_DIR_OUT 0x00
#define USB_DIR_IN 0x80
#define USB_DIR_MASK 0x80
#define RH_GET_PORT_STATUS 0
#define RH_SET_PORT_STATUS 1
#define RH_CLEAR_PORT_FEATURE 2
#define RH_SET_PORT_FEATURE 3
/*
* Port feature numbers
*/
#define PORT_FEAT_CONNECTION 0
#define PORT_FEAT_ENABLE 1
#define PORT_FEAT_SUSPEND 2
#define PORT_FEAT_OVER_CURRENT 3
#define PORT_FEAT_RESET 4
#define PORT_FEAT_POWER 8
#define PORT_FEAT_LOWSPEED 9
#define PORT_FEAT_HIGHSPEED 10
#define PORT_FEAT_C_CONNECTION 16
#define PORT_FEAT_C_ENABLE 17
#define PORT_FEAT_C_SUSPEND 18
#define PORT_FEAT_C_OVER_CURRENT 19
#define PORT_FEAT_C_RESET 20
/*
The HcRhPortStatus[1:NDP] register is used to control and report port events on a per-port
basis. NumberDownstreamPorts represents the number of HcRhPortStatus registers that are
implemented in hardware. The lower word is used to reflect the port status, whereas the upper
word reflects the status change bits. Some status bits are implemented with special write behavior
(see below). If a transaction (token through handshake) is in progress when a write to change
port status occurs, the resulting port status change must be postponed until the transaction
completes. Reserved bits should always be written '0'.
*/
#define PORT_CCS 0x00000001UL /* R:CurrentConnectStatus - W:ClearPortEnable */
#define PORT_PES 0x00000002UL /* R:PortEnableStatus - W:SetPortEnable */
#define PORT_PSS 0x00000004UL /* R:PortSuspendStatus - W:SetPortSuspend */
#define PORT_POCI 0x00000008UL /* R:PortOverCurrentIndicator - W:ClearSuspendStatus */
#define PORT_PRS 0x00000010UL /* R:PortResetStatus - W: SetPortReset */
#define PORT_PPS 0x00000100UL /* R:PortPowerStatus - W: SetPortPower */
#define PORT_LSDA 0x00000200UL /* R:LowSpeedDeviceAttached - W:ClearPortPower */
#define PORT_CCSC 0x00010000UL
#define PORT_PESC 0x00020000UL
#define PORT_PSSC 0x00040000UL
#define PORT_POCIC 0x00080000UL
#define PORT_PRSC 0x00100000UL
/*
*Hub Status & Hub Change bit masks
*/
#define HUB_STATUS_LOCAL_POWER 0x0001
#define HUB_STATUS_OVERCURRENT 0x0002
#define HUB_CHANGE_LOCAL_POWER 0x0001
#define HUB_CHANGE_OVERCURRENT 0x0002
#define USB_EP_ATTR(attr) (attr & USB_EP_ATTR_TYPE_MASK)
#define USB_EP_DESC_NUM(addr) (addr & USB_EP_DESC_NUM_MASK)
#define uswap_32(x) \
((((x) & 0xff000000) >> 24) | \
(((x) & 0x00ff0000) >> 8) | \
(((x) & 0x0000ff00) << 8) | \
(((x) & 0x000000ff) << 24))
typedef void (*func_callback)(void *context);
#define UPIPE_STATUS_OK 0x00
#define UPIPE_STATUS_STALL 0x01
#define UPIPE_STATUS_ERROR 0x02
struct uhcd;
struct uifinst;
struct uhubinst;
enum umsg_type
{
USB_MSG_CONNECT_CHANGE,
USB_MSG_CALLBACK,
};
typedef enum umsg_type umsg_type;
struct usb_descriptor
{
rt_uint8_t bLength;
rt_uint8_t type;
};
typedef struct usb_descriptor* udesc_t;
struct udevice_descriptor
{
rt_uint8_t bLength;
rt_uint8_t type;
rt_uint16_t bcdUSB;
rt_uint8_t bDeviceClass;
rt_uint8_t bDeviceSubClass;
rt_uint8_t bDeviceProtocol;
rt_uint8_t bMaxPacketSize0;
rt_uint16_t idVendor;
rt_uint16_t idProduct;
rt_uint16_t bcdDevice;
rt_uint8_t iManufacturer;
rt_uint8_t iProduct;
rt_uint8_t iSerialNumber;
rt_uint8_t bNumConfigurations;
};
typedef struct udevice_descriptor* udev_desc_t;
struct uconfig_descriptor
{
rt_uint8_t bLength;
rt_uint8_t type;
rt_uint16_t wTotalLength;
rt_uint8_t bNumInterfaces;
rt_uint8_t bConfigurationValue;
rt_uint8_t iConfiguration;
rt_uint8_t bmAttributes;
rt_uint8_t MaxPower;
};
typedef struct uconfig_descriptor* ucfg_desc_t;
struct uinterface_descriptor
{
rt_uint8_t bLength;
rt_uint8_t type;
rt_uint8_t bInterfaceNumber;
rt_uint8_t bAlternateSetting;
rt_uint8_t bNumEndpoints;
rt_uint8_t bInterfaceClass;
rt_uint8_t bInterfaceSubClass;
rt_uint8_t bInterfaceProtocol;
rt_uint8_t iInterface;
};
typedef struct uinterface_descriptor* uintf_desc_t;
struct uendpoint_descriptor
{
rt_uint8_t bLength;
rt_uint8_t type;
rt_uint8_t bEndpointAddress;
rt_uint8_t bmAttributes;
rt_uint16_t wMaxPacketSize;
rt_uint8_t bInterval;
};
typedef struct uendpoint_descriptor* uep_desc_t;
struct ustring_descriptor
{
rt_uint8_t bLength;
rt_uint8_t type;
rt_uint8_t* String;
};
typedef struct ustring_descriptor* ustr_desc_t;
struct uhub_descriptor
{
rt_uint8_t length;
rt_uint8_t type;
rt_uint8_t num_ports;
rt_uint16_t characteristics;
rt_uint8_t pwron_to_good; /* power on to power good */
rt_uint8_t current;
rt_uint8_t removable[8];
rt_uint8_t pwr_ctl[8];
};
typedef struct uhub_descriptor* uhub_desc_t;
struct ureqest
{
rt_uint8_t request_type;
rt_uint8_t request;
rt_uint16_t value;
rt_uint16_t index;
rt_uint16_t length;
};
typedef struct ureqest* ureq_t;
struct uclass_driver
{
rt_list_t list;
@@ -315,13 +47,6 @@ struct uclass_driver
rt_err_t (*run)(void* arg);
rt_err_t (*stop)(void* arg);
const char* manufacturer;
const char* model;
const char* description;
const char* version;
const char* uri;
const char* serial;
void* user_data;
};
@@ -376,21 +101,6 @@ struct upipe
};
typedef struct upipe* upipe_t;
struct umsg
{
umsg_type type;
union
{
struct uhubinst* uhub;
struct
{
func_callback function;
void *context;
}cb;
}content;
};
typedef struct umsg* umsg_t;
struct uhubinst
{
struct uhub_descriptor hub_desc;
@@ -427,6 +137,28 @@ struct uhcd
};
typedef struct uhcd* uhcd_t;
enum uhost_msg_type
{
USB_MSG_CONNECT_CHANGE,
USB_MSG_CALLBACK,
};
typedef enum uhost_msg_type uhost_msg_type;
struct uhost_msg
{
uhost_msg_type type;
union
{
struct uhubinst* uhub;
struct
{
func_callback function;
void *context;
}cb;
}content;
};
typedef struct uhost_msg* uhost_msg_t;
/* usb host system interface */
void rt_usb_host_init(void);
void rt_usb_hub_thread(void);
@@ -480,7 +212,7 @@ rt_err_t rt_usb_hub_clear_port_feature(uhubinst_t uhub, rt_uint16_t port,
rt_err_t rt_usb_hub_set_port_feature(uhubinst_t uhub, rt_uint16_t port,
rt_uint16_t feature);
rt_err_t rt_usb_hub_reset_port(uhubinst_t uhub, rt_uint16_t port);
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);
/* usb host controller driver interface */
rt_inline rt_err_t rt_usb_hcd_alloc_pipe(uhcd_t hcd, upipe_t* pipe,
@@ -488,11 +220,6 @@ rt_inline rt_err_t rt_usb_hcd_alloc_pipe(uhcd_t hcd, upipe_t* pipe,
{
if(ifinst == RT_NULL) return -RT_EIO;
/* parameter check */
RT_ASSERT(hcd != RT_NULL);
RT_ASSERT(hcd->ops != RT_NULL);
RT_ASSERT(hcd->ops->alloc_pipe!= RT_NULL);
return hcd->ops->alloc_pipe(pipe, ifinst, ep, callback);
}
@@ -500,11 +227,6 @@ rt_inline rt_err_t rt_usb_hcd_free_pipe(uhcd_t hcd, upipe_t pipe)
{
RT_ASSERT(pipe != RT_NULL);
/* parameter check */
RT_ASSERT(hcd != RT_NULL);
RT_ASSERT(hcd->ops != RT_NULL);
RT_ASSERT(hcd->ops->free_pipe!= RT_NULL);
return hcd->ops->free_pipe(pipe);
}
@@ -517,11 +239,6 @@ rt_inline int rt_usb_hcd_bulk_xfer(uhcd_t hcd, upipe_t pipe, void* buffer,
if(pipe->ifinst->uinst->status == UINST_STATUS_IDLE)
return -1;
/* parameter check */
RT_ASSERT(hcd != RT_NULL);
RT_ASSERT(hcd->ops != RT_NULL);
RT_ASSERT(hcd->ops->bulk_xfer!= RT_NULL);
return hcd->ops->bulk_xfer(pipe, buffer, nbytes, timeout);
}
@@ -530,11 +247,6 @@ rt_inline int rt_usb_hcd_control_xfer(uhcd_t hcd, uinst_t uinst, ureq_t setup,
{
if(uinst->status == UINST_STATUS_IDLE) return -1;
/* parameter check */
RT_ASSERT(hcd != RT_NULL);
RT_ASSERT(hcd->ops != RT_NULL);
RT_ASSERT(hcd->ops->ctl_xfer!= RT_NULL);
return hcd->ops->ctl_xfer(uinst, setup, buffer, nbytes, timeout);
}
@@ -547,20 +259,12 @@ rt_inline int rt_usb_hcd_int_xfer(uhcd_t hcd, upipe_t pipe, void* buffer,
if(pipe->ifinst->uinst->status == UINST_STATUS_IDLE)
return -1;
RT_ASSERT(hcd != RT_NULL);
RT_ASSERT(hcd->ops != RT_NULL);
RT_ASSERT(hcd->ops->int_xfer!= RT_NULL);
return hcd->ops->int_xfer(pipe, buffer, nbytes, timeout);
}
rt_inline rt_err_t rt_usb_hcd_hub_control(uhcd_t hcd, rt_uint16_t port,
rt_uint8_t cmd, void *args)
{
RT_ASSERT(hcd != RT_NULL);
RT_ASSERT(hcd->ops != RT_NULL);
RT_ASSERT(hcd->ops->hub_ctrl != RT_NULL);
return hcd->ops->hub_ctrl(port, cmd, args);
}