提交 1016e3ae 编写于 作者: qiuyiuestc's avatar qiuyiuestc

add ADK protocol implement & format code style

git-svn-id: https://rt-thread.googlecode.com/svn/trunk@2219 bbd45198-f89e-11dd-88c7-29a3b14d5316
上级 70cee4b8
...@@ -17,183 +17,183 @@ ...@@ -17,183 +17,183 @@
#include <rtthread.h> #include <rtthread.h>
#define RT_DEBUG_USB 0x01 #define RT_DEBUG_USB 0x01
#define USB_MAX_DEVICE 0x20 #define USB_MAX_DEVICE 0x20
#define USB_MAX_INTERFACE 0x08 #define USB_MAX_INTERFACE 0x08
#define USB_HUB_PORT_NUM 0x04 #define USB_HUB_PORT_NUM 0x04
#define SIZEOF_USB_REQUEST 0x08 #define SIZEOF_USB_REQUEST 0x08
#define UINST_STATUS_IDLE 0x00 #define UINST_STATUS_IDLE 0x00
#define UINST_STATUS_BUSY 0x01 #define UINST_STATUS_BUSY 0x01
#define UINST_STATUS_ERROR 0x02 #define UINST_STATUS_ERROR 0x02
#define UPIPE_STATUS_OK 0x00 #define UPIPE_STATUS_OK 0x00
#define UPIPE_STATUS_STALL 0x01 #define UPIPE_STATUS_STALL 0x01
#define UPIPE_STATUS_ERROR 0x02 #define UPIPE_STATUS_ERROR 0x02
#define USB_CLASS_DEVICE 0x00 #define USB_CLASS_DEVICE 0x00
#define USB_CLASS_AUDIO 0x01 #define USB_CLASS_AUDIO 0x01
#define USB_CLASS_CDC 0x02 #define USB_CLASS_CDC 0x02
#define USB_CLASS_HID 0x03 #define USB_CLASS_HID 0x03
#define USB_CLASS_PHYSICAL 0x05 #define USB_CLASS_PHYSICAL 0x05
#define USB_CLASS_IMAGE 0x06 #define USB_CLASS_IMAGE 0x06
#define USB_CLASS_PRINTER 0x07 #define USB_CLASS_PRINTER 0x07
#define USB_CLASS_MASS_STORAGE 0x08 #define USB_CLASS_MASS_STORAGE 0x08
#define USB_CLASS_HUB 0x09 #define USB_CLASS_HUB 0x09
#define USB_CLASS_CDC_DATA 0x0a #define USB_CLASS_CDC_DATA 0x0a
#define USB_CLASS_SMART_CARD 0x0b #define USB_CLASS_SMART_CARD 0x0b
#define USB_CLASS_SECURITY 0x0d #define USB_CLASS_SECURITY 0x0d
#define USB_CLASS_VIDEO 0x0e #define USB_CLASS_VIDEO 0x0e
#define USB_CLASS_HEALTHCARE 0x0f #define USB_CLASS_HEALTHCARE 0x0f
#define USB_CLASS_DIAG_DEVICE 0xdc #define USB_CLASS_DIAG_DEVICE 0xdc
#define USB_CLASS_WIRELESS 0xe0 #define USB_CLASS_WIRELESS 0xe0
#define USB_CLASS_MISC 0xef #define USB_CLASS_MISC 0xef
#define USB_CLASS_APP_SPECIFIC 0xfe #define USB_CLASS_APP_SPECIFIC 0xfe
#define USB_CLASS_VEND_SPECIFIC 0xff #define USB_CLASS_VEND_SPECIFIC 0xff
#define USB_DESC_TYPE_DEVICE 0x01 #define USB_DESC_TYPE_DEVICE 0x01
#define USB_DESC_TYPE_CONFIGURATION 0x02 #define USB_DESC_TYPE_CONFIGURATION 0x02
#define USB_DESC_TYPE_STRING 0x03 #define USB_DESC_TYPE_STRING 0x03
#define USB_DESC_TYPE_INTERFACE 0x04 #define USB_DESC_TYPE_INTERFACE 0x04
#define USB_DESC_TYPE_ENDPOINT 0x05 #define USB_DESC_TYPE_ENDPOINT 0x05
#define USB_DESC_TYPE_DEVICEQUALIFIER 0x06 #define USB_DESC_TYPE_DEVICEQUALIFIER 0x06
#define USB_DESC_TYPE_OTHERSPEED 0x07 #define USB_DESC_TYPE_OTHERSPEED 0x07
#define USB_DESC_TYPE_HID 0x21 #define USB_DESC_TYPE_HID 0x21
#define USB_DESC_TYPE_REPORT 0x22 #define USB_DESC_TYPE_REPORT 0x22
#define USB_DESC_TYPE_PHYSICAL 0x23 #define USB_DESC_TYPE_PHYSICAL 0x23
#define USB_DESC_TYPE_HUB 0x29 #define USB_DESC_TYPE_HUB 0x29
#define USB_REQ_TYPE_STANDARD 0x00 #define USB_REQ_TYPE_STANDARD 0x00
#define USB_REQ_TYPE_CLASS 0x20 #define USB_REQ_TYPE_CLASS 0x20
#define USB_REQ_TYPE_VENDOR 0x40 #define USB_REQ_TYPE_VENDOR 0x40
#define USB_REQ_TYPE_TYPE_MASK 0x60 #define USB_REQ_TYPE_TYPE_MASK 0x60
#define USB_REQ_TYPE_DIR_OUT 0x00 #define USB_REQ_TYPE_DIR_OUT 0x00
#define USB_REQ_TYPE_DIR_IN 0x80 #define USB_REQ_TYPE_DIR_IN 0x80
#define USB_REQ_TYPE_DEVICE 0x00 #define USB_REQ_TYPE_DEVICE 0x00
#define USB_REQ_TYPE_INTERFACE 0x01 #define USB_REQ_TYPE_INTERFACE 0x01
#define USB_REQ_TYPE_ENDPOINT 0x02 #define USB_REQ_TYPE_ENDPOINT 0x02
#define USB_REQ_TYPE_OTHER 0x03 #define USB_REQ_TYPE_OTHER 0x03
#define USB_REQ_TYPE_RECIPIENT_MASK 0x1f #define USB_REQ_TYPE_RECIPIENT_MASK 0x1f
#define USB_FEATURE_ENDPOINT_HALT 0x00 #define USB_FEATURE_ENDPOINT_HALT 0x00
#define USB_FEATURE_DEV_REMOTE_WAKEUP 0x01 #define USB_FEATURE_DEV_REMOTE_WAKEUP 0x01
#define USB_FEATURE_TEST_MODE 0x02 #define USB_FEATURE_TEST_MODE 0x02
#define USB_REQ_GET_STATUS 0x00 #define USB_REQ_GET_STATUS 0x00
#define USB_REQ_CLEAR_FEATURE 0x01 #define USB_REQ_CLEAR_FEATURE 0x01
#define USB_REQ_SET_FEATURE 0x03 #define USB_REQ_SET_FEATURE 0x03
#define USB_REQ_SET_ADDRESS 0x05 #define USB_REQ_SET_ADDRESS 0x05
#define USB_REQ_GET_DESCRIPTOR 0x06 #define USB_REQ_GET_DESCRIPTOR 0x06
#define USB_REQ_SET_DESCRIPTOR 0x07 #define USB_REQ_SET_DESCRIPTOR 0x07
#define USB_REQ_GET_CONFIGURATION 0x08 #define USB_REQ_GET_CONFIGURATION 0x08
#define USB_REQ_SET_CONFIGURATION 0x09 #define USB_REQ_SET_CONFIGURATION 0x09
#define USB_REQ_GET_INTERFACE 0x0A #define USB_REQ_GET_INTERFACE 0x0A
#define USB_REQ_SET_INTERFACE 0x0B #define USB_REQ_SET_INTERFACE 0x0B
#define USB_REQ_SYNCH_FRAME 0x0C #define USB_REQ_SYNCH_FRAME 0x0C
#define USB_REQ_SET_ENCRYPTION 0x0D #define USB_REQ_SET_ENCRYPTION 0x0D
#define USB_REQ_GET_ENCRYPTION 0x0E #define USB_REQ_GET_ENCRYPTION 0x0E
#define USB_REQ_RPIPE_ABORT 0x0E #define USB_REQ_RPIPE_ABORT 0x0E
#define USB_REQ_SET_HANDSHAKE 0x0F #define USB_REQ_SET_HANDSHAKE 0x0F
#define USB_REQ_RPIPE_RESET 0x0F #define USB_REQ_RPIPE_RESET 0x0F
#define USB_REQ_GET_HANDSHAKE 0x10 #define USB_REQ_GET_HANDSHAKE 0x10
#define USB_REQ_SET_CONNECTION 0x11 #define USB_REQ_SET_CONNECTION 0x11
#define USB_REQ_SET_SECURITY_DATA 0x12 #define USB_REQ_SET_SECURITY_DATA 0x12
#define USB_REQ_GET_SECURITY_DATA 0x13 #define USB_REQ_GET_SECURITY_DATA 0x13
#define USB_REQ_SET_WUSB_DATA 0x14 #define USB_REQ_SET_WUSB_DATA 0x14
#define USB_REQ_LOOPBACK_DATA_WRITE 0x15 #define USB_REQ_LOOPBACK_DATA_WRITE 0x15
#define USB_REQ_LOOPBACK_DATA_READ 0x16 #define USB_REQ_LOOPBACK_DATA_READ 0x16
#define USB_REQ_SET_INTERFACE_DS 0x17 #define USB_REQ_SET_INTERFACE_DS 0x17
#define USB_PID_OUT 0x01 #define USB_PID_OUT 0x01
#define USB_PID_ACK 0x02 #define USB_PID_ACK 0x02
#define USB_PID_DATA0 0x03 #define USB_PID_DATA0 0x03
#define USB_PID_SOF 0x05 #define USB_PID_SOF 0x05
#define USB_PID_IN 0x09 #define USB_PID_IN 0x09
#define USB_PID_NACK 0x0A #define USB_PID_NACK 0x0A
#define USB_PID_DATA1 0x0B #define USB_PID_DATA1 0x0B
#define USB_PID_PRE 0x0C #define USB_PID_PRE 0x0C
#define USB_PID_SETUP 0x0D #define USB_PID_SETUP 0x0D
#define USB_PID_STALL 0x0E #define USB_PID_STALL 0x0E
#define USB_EP_DESC_OUT 0x00 #define USB_EP_DESC_OUT 0x00
#define USB_EP_DESC_IN 0x80 #define USB_EP_DESC_IN 0x80
#define USB_EP_DESC_NUM_MASK 0x0f #define USB_EP_DESC_NUM_MASK 0x0f
#define USB_EP_ATTR_CONTROL 0x00 #define USB_EP_ATTR_CONTROL 0x00
#define USB_EP_ATTR_ISOC 0x01 #define USB_EP_ATTR_ISOC 0x01
#define USB_EP_ATTR_BULK 0x02 #define USB_EP_ATTR_BULK 0x02
#define USB_EP_ATTR_INT 0x03 #define USB_EP_ATTR_INT 0x03
#define USB_EP_ATTR_TYPE_MASK 0x03 #define USB_EP_ATTR_TYPE_MASK 0x03
#define USB_EPNO_MASK 0x7f #define USB_EPNO_MASK 0x7f
#define USB_DIR_OUT 0x00 #define USB_DIR_OUT 0x00
#define USB_DIR_IN 0x80 #define USB_DIR_IN 0x80
#define USB_DIR_MASK 0x80 #define USB_DIR_MASK 0x80
#define RH_GET_PORT_STATUS 0 #define RH_GET_PORT_STATUS 0
#define RH_SET_PORT_STATUS 1 #define RH_SET_PORT_STATUS 1
#define RH_CLEAR_PORT_FEATURE 2 #define RH_CLEAR_PORT_FEATURE 2
#define RH_SET_PORT_FEATURE 3 #define RH_SET_PORT_FEATURE 3
/* /*
* Port feature numbers * Port feature numbers
*/ */
#define PORT_FEAT_CONNECTION 0 #define PORT_FEAT_CONNECTION 0
#define PORT_FEAT_ENABLE 1 #define PORT_FEAT_ENABLE 1
#define PORT_FEAT_SUSPEND 2 #define PORT_FEAT_SUSPEND 2
#define PORT_FEAT_OVER_CURRENT 3 #define PORT_FEAT_OVER_CURRENT 3
#define PORT_FEAT_RESET 4 #define PORT_FEAT_RESET 4
#define PORT_FEAT_POWER 8 #define PORT_FEAT_POWER 8
#define PORT_FEAT_LOWSPEED 9 #define PORT_FEAT_LOWSPEED 9
#define PORT_FEAT_HIGHSPEED 10 #define PORT_FEAT_HIGHSPEED 10
#define PORT_FEAT_C_CONNECTION 16 #define PORT_FEAT_C_CONNECTION 16
#define PORT_FEAT_C_ENABLE 17 #define PORT_FEAT_C_ENABLE 17
#define PORT_FEAT_C_SUSPEND 18 #define PORT_FEAT_C_SUSPEND 18
#define PORT_FEAT_C_OVER_CURRENT 19 #define PORT_FEAT_C_OVER_CURRENT 19
#define PORT_FEAT_C_RESET 20 #define PORT_FEAT_C_RESET 20
/* /*
The HcRhPortStatus[1:NDP] register is used to control and report port events on a per-port 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 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 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 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 (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 port status occurs, the resulting port status change must be postponed until the transaction
completes. Reserved bits should always be written '0'. completes. Reserved bits should always be written '0'.
*/ */
#define PORT_CCS 0x00000001UL /* R:CurrentConnectStatus - W:ClearPortEnable */ #define PORT_CCS 0x00000001UL /* R:CurrentConnectStatus - W:ClearPortEnable */
#define PORT_PES 0x00000002UL /* R:PortEnableStatus - W:SetPortEnable */ #define PORT_PES 0x00000002UL /* R:PortEnableStatus - W:SetPortEnable */
#define PORT_PSS 0x00000004UL /* R:PortSuspendStatus - W:SetPortSuspend */ #define PORT_PSS 0x00000004UL /* R:PortSuspendStatus - W:SetPortSuspend */
#define PORT_POCI 0x00000008UL /* R:PortOverCurrentIndicator - W:ClearSuspendStatus */ #define PORT_POCI 0x00000008UL /* R:PortOverCurrentIndicator - W:ClearSuspendStatus */
#define PORT_PRS 0x00000010UL /* R:PortResetStatus - W: SetPortReset */ #define PORT_PRS 0x00000010UL /* R:PortResetStatus - W: SetPortReset */
#define PORT_PPS 0x00000100UL /* R:PortPowerStatus - W: SetPortPower */ #define PORT_PPS 0x00000100UL /* R:PortPowerStatus - W: SetPortPower */
#define PORT_LSDA 0x00000200UL /* R:LowSpeedDeviceAttached - W:ClearPortPower */ #define PORT_LSDA 0x00000200UL /* R:LowSpeedDeviceAttached - W:ClearPortPower */
#define PORT_CCSC 0x00010000UL #define PORT_CCSC 0x00010000UL
#define PORT_PESC 0x00020000UL #define PORT_PESC 0x00020000UL
#define PORT_PSSC 0x00040000UL #define PORT_PSSC 0x00040000UL
#define PORT_POCIC 0x00080000UL #define PORT_POCIC 0x00080000UL
#define PORT_PRSC 0x00100000UL #define PORT_PRSC 0x00100000UL
/* /*
*Hub Status & Hub Change bit masks *Hub Status & Hub Change bit masks
*/ */
#define HUB_STATUS_LOCAL_POWER 0x0001 #define HUB_STATUS_LOCAL_POWER 0x0001
#define HUB_STATUS_OVERCURRENT 0x0002 #define HUB_STATUS_OVERCURRENT 0x0002
#define HUB_CHANGE_LOCAL_POWER 0x0001 #define HUB_CHANGE_LOCAL_POWER 0x0001
#define HUB_CHANGE_OVERCURRENT 0x0002 #define HUB_CHANGE_OVERCURRENT 0x0002
#define USB_EP_ATTR(attr) (attr & USB_EP_ATTR_TYPE_MASK) #define USB_EP_ATTR(attr) (attr & USB_EP_ATTR_TYPE_MASK)
#define USB_EP_DESC_NUM(addr) (addr & USB_EP_DESC_NUM_MASK) #define USB_EP_DESC_NUM(addr) (addr & USB_EP_DESC_NUM_MASK)
#define uswap_32(x) \ #define uswap_32(x) \
((((x) & 0xff000000) >> 24) | \ ((((x) & 0xff000000) >> 24) | \
(((x) & 0x00ff0000) >> 8) | \ (((x) & 0x00ff0000) >> 8) | \
(((x) & 0x0000ff00) << 8) | \ (((x) & 0x0000ff00) << 8) | \
(((x) & 0x000000ff) << 24)) (((x) & 0x000000ff) << 24))
typedef void (*func_callback)(void *context); typedef void (*func_callback)(void *context);
...@@ -203,216 +203,216 @@ struct uhubinst; ...@@ -203,216 +203,216 @@ struct uhubinst;
enum umsg_type enum umsg_type
{ {
USB_MSG_CONNECT_CHANGE, USB_MSG_CONNECT_CHANGE,
USB_MSG_CALLBACK, USB_MSG_CALLBACK,
}; };
typedef enum umsg_type umsg_type; typedef enum umsg_type umsg_type;
struct usb_descriptor struct usb_descriptor
{ {
rt_uint8_t bLength; rt_uint8_t bLength;
rt_uint8_t type; rt_uint8_t type;
}; };
typedef struct usb_descriptor* udesc_t; typedef struct usb_descriptor* udesc_t;
struct udevice_descriptor struct udevice_descriptor
{ {
rt_uint8_t bLength; rt_uint8_t bLength;
rt_uint8_t type; rt_uint8_t type;
rt_uint16_t bcdUSB; rt_uint16_t bcdUSB;
rt_uint8_t bDeviceClass; rt_uint8_t bDeviceClass;
rt_uint8_t bDeviceSubClass; rt_uint8_t bDeviceSubClass;
rt_uint8_t bDeviceProtocol; rt_uint8_t bDeviceProtocol;
rt_uint8_t bMaxPacketSize0; rt_uint8_t bMaxPacketSize0;
rt_uint16_t idVendor; rt_uint16_t idVendor;
rt_uint16_t idProduct; rt_uint16_t idProduct;
rt_uint16_t bcdDevice; rt_uint16_t bcdDevice;
rt_uint8_t iManufacturer; rt_uint8_t iManufacturer;
rt_uint8_t iProduct; rt_uint8_t iProduct;
rt_uint8_t iSerialNumber; rt_uint8_t iSerialNumber;
rt_uint8_t bNumConfigurations; rt_uint8_t bNumConfigurations;
}; };
typedef struct udevice_descriptor* udev_desc_t; typedef struct udevice_descriptor* udev_desc_t;
struct uconfig_descriptor struct uconfig_descriptor
{ {
rt_uint8_t bLength; rt_uint8_t bLength;
rt_uint8_t type; rt_uint8_t type;
rt_uint16_t wTotalLength; rt_uint16_t wTotalLength;
rt_uint8_t bNumInterfaces; rt_uint8_t bNumInterfaces;
rt_uint8_t bConfigurationValue; rt_uint8_t bConfigurationValue;
rt_uint8_t iConfiguration; rt_uint8_t iConfiguration;
rt_uint8_t bmAttributes; rt_uint8_t bmAttributes;
rt_uint8_t MaxPower; rt_uint8_t MaxPower;
}; };
typedef struct uconfig_descriptor* ucfg_desc_t; typedef struct uconfig_descriptor* ucfg_desc_t;
struct uinterface_descriptor struct uinterface_descriptor
{ {
rt_uint8_t bLength; rt_uint8_t bLength;
rt_uint8_t type; rt_uint8_t type;
rt_uint8_t bInterfaceNumber; rt_uint8_t bInterfaceNumber;
rt_uint8_t bAlternateSetting; rt_uint8_t bAlternateSetting;
rt_uint8_t bNumEndpoints; rt_uint8_t bNumEndpoints;
rt_uint8_t bInterfaceClass; rt_uint8_t bInterfaceClass;
rt_uint8_t bInterfaceSubClass; rt_uint8_t bInterfaceSubClass;
rt_uint8_t bInterfaceProtocol; rt_uint8_t bInterfaceProtocol;
rt_uint8_t iInterface; rt_uint8_t iInterface;
}; };
typedef struct uinterface_descriptor* uintf_desc_t; typedef struct uinterface_descriptor* uintf_desc_t;
struct uendpoint_descriptor struct uendpoint_descriptor
{ {
rt_uint8_t bLength; rt_uint8_t bLength;
rt_uint8_t type; rt_uint8_t type;
rt_uint8_t bEndpointAddress; rt_uint8_t bEndpointAddress;
rt_uint8_t bmAttributes; rt_uint8_t bmAttributes;
rt_uint16_t wMaxPacketSize; rt_uint16_t wMaxPacketSize;
rt_uint8_t bInterval; rt_uint8_t bInterval;
}; };
typedef struct uendpoint_descriptor* uep_desc_t; typedef struct uendpoint_descriptor* uep_desc_t;
struct ustring_descriptor struct ustring_descriptor
{ {
rt_uint8_t bLength; rt_uint8_t bLength;
rt_uint8_t type; rt_uint8_t type;
rt_uint8_t* String; rt_uint8_t* String;
}; };
typedef struct ustring_descriptor* ustr_desc_t; typedef struct ustring_descriptor* ustr_desc_t;
struct uhub_descriptor struct uhub_descriptor
{ {
rt_uint8_t length; rt_uint8_t length;
rt_uint8_t type; rt_uint8_t type;
rt_uint8_t num_ports; rt_uint8_t num_ports;
rt_uint16_t characteristics; rt_uint16_t characteristics;
rt_uint8_t pwron_to_good; /* power on to power good */ rt_uint8_t pwron_to_good; /* power on to power good */
rt_uint8_t current; rt_uint8_t current;
rt_uint8_t removable[8]; rt_uint8_t removable[8];
rt_uint8_t pwr_ctl[8]; rt_uint8_t pwr_ctl[8];
}; };
typedef struct uhub_descriptor* uhub_desc_t; typedef struct uhub_descriptor* uhub_desc_t;
struct ureqest struct ureqest
{ {
rt_uint8_t request_type; rt_uint8_t request_type;
rt_uint8_t request; rt_uint8_t request;
rt_uint16_t value; rt_uint16_t value;
rt_uint16_t index; rt_uint16_t index;
rt_uint16_t length; rt_uint16_t length;
}; };
typedef struct ureqest* ureq_t; typedef struct ureqest* ureq_t;
struct uclass_driver struct uclass_driver
{ {
rt_list_t list; rt_list_t list;
int class_code; int class_code;
int subclass_code; int subclass_code;
rt_err_t (*run)(void* arg); rt_err_t (*run)(void* arg);
rt_err_t (*stop)(void* arg); rt_err_t (*stop)(void* arg);
void* user_data; void* user_data;
}; };
typedef struct uclass_driver* ucd_t; typedef struct uclass_driver* ucd_t;
struct uprotocal struct uprotocal
{ {
rt_list_t list; rt_list_t list;
int pro_id; int pro_id;
rt_err_t (*init)(void* arg); rt_err_t (*init)(void* arg);
rt_err_t (*callback)(void* arg); rt_err_t (*callback)(void* arg);
}; };
typedef struct uprotocal* uprotocal_t; typedef struct uprotocal* uprotocal_t;
struct uinstance struct uinstance
{ {
struct udevice_descriptor dev_desc; struct udevice_descriptor dev_desc;
ucfg_desc_t cfg_desc; ucfg_desc_t cfg_desc;
struct uhcd *hcd; struct uhcd *hcd;
rt_uint8_t status; rt_uint8_t status;
rt_uint8_t type; rt_uint8_t type;
rt_uint8_t index; rt_uint8_t index;
rt_uint8_t address; rt_uint8_t address;
rt_uint8_t speed; rt_uint8_t speed;
rt_uint8_t max_packet_size; rt_uint8_t max_packet_size;
rt_uint8_t port; rt_uint8_t port;
struct uhubinst* parent; struct uhubinst* parent;
struct uifinst* ifinst[USB_MAX_INTERFACE]; struct uifinst* ifinst[USB_MAX_INTERFACE];
}; };
typedef struct uinstance* uinst_t; typedef struct uinstance* uinst_t;
struct uifinst struct uifinst
{ {
uinst_t uinst; uinst_t uinst;
uintf_desc_t intf_desc; uintf_desc_t intf_desc;
ucd_t drv; ucd_t drv;
void *user_data; void *user_data;
}; };
typedef struct uifinst* uifinst_t; typedef struct uifinst* uifinst_t;
struct upipe struct upipe
{ {
rt_uint32_t status; rt_uint32_t status;
struct uendpoint_descriptor ep; struct uendpoint_descriptor ep;
uifinst_t ifinst; uifinst_t ifinst;
func_callback callback; func_callback callback;
void* user_data; void* user_data;
}; };
typedef struct upipe* upipe_t; typedef struct upipe* upipe_t;
struct umsg struct umsg
{ {
umsg_type type; umsg_type type;
union union
{ {
struct uhubinst* uhub; struct uhubinst* uhub;
struct struct
{ {
func_callback function; func_callback function;
void *context; void *context;
}cb; }cb;
}content; }content;
}; };
typedef struct umsg* umsg_t; typedef struct umsg* umsg_t;
struct uhubinst struct uhubinst
{ {
struct uhub_descriptor hub_desc; struct uhub_descriptor hub_desc;
rt_uint8_t num_ports; rt_uint8_t num_ports;
rt_uint32_t port_status[USB_HUB_PORT_NUM]; rt_uint32_t port_status[USB_HUB_PORT_NUM];
struct uinstance* child[USB_HUB_PORT_NUM]; struct uinstance* child[USB_HUB_PORT_NUM];
rt_bool_t is_roothub; rt_bool_t is_roothub;
upipe_t pipe_in; upipe_t pipe_in;
rt_uint8_t buffer[8]; rt_uint8_t buffer[8];
struct uinstance* self; struct uinstance* self;
struct uhcd *hcd; struct uhcd *hcd;
}; };
typedef struct uhubinst* uhubinst_t; typedef struct uhubinst* uhubinst_t;
struct uhcd_ops struct uhcd_ops
{ {
int (*ctl_xfer)(uinst_t inst, ureq_t setup, void* buffer, int nbytes, int (*ctl_xfer)(uinst_t inst, ureq_t setup, void* buffer, int nbytes,
int timeout); int timeout);
int (*bulk_xfer)(upipe_t pipe, void* buffer, int nbytes, int timeout); int (*bulk_xfer)(upipe_t pipe, void* buffer, int nbytes, int timeout);
int (*int_xfer)(upipe_t pipe, void* buffer, int nbytes, int timeout); int (*int_xfer)(upipe_t pipe, void* buffer, int nbytes, int timeout);
int (*iso_xfer)(upipe_t pipe, void* buffer, int nbytes, int timeout); int (*iso_xfer)(upipe_t pipe, void* buffer, int nbytes, int timeout);
rt_err_t (*alloc_pipe)(struct upipe** pipe, uifinst_t ifinst, uep_desc_t ep, rt_err_t (*alloc_pipe)(struct upipe** pipe, uifinst_t ifinst, uep_desc_t ep,
func_callback callback); func_callback callback);
rt_err_t (*free_pipe)(upipe_t pipe); rt_err_t (*free_pipe)(upipe_t pipe);
rt_err_t (*hub_ctrl)(rt_uint16_t port, rt_uint8_t cmd, void *args); rt_err_t (*hub_ctrl)(rt_uint16_t port, rt_uint8_t cmd, void *args);
}; };
struct uhcd struct uhcd
{ {
struct rt_device parent; struct rt_device parent;
struct uhcd_ops* ops; struct uhcd_ops* ops;
}; };
typedef struct uhcd* uhcd_t; typedef struct uhcd* uhcd_t;
...@@ -425,15 +425,15 @@ uinst_t rt_usb_alloc_instance(void); ...@@ -425,15 +425,15 @@ uinst_t rt_usb_alloc_instance(void);
rt_err_t rt_usb_attatch_instance(uinst_t uinst); rt_err_t rt_usb_attatch_instance(uinst_t uinst);
rt_err_t rt_usb_detach_instance(uinst_t uinst); rt_err_t rt_usb_detach_instance(uinst_t uinst);
rt_err_t rt_usb_get_descriptor(uinst_t uinst, rt_uint8_t type, void* buffer, rt_err_t rt_usb_get_descriptor(uinst_t uinst, rt_uint8_t type, void* buffer,
int nbytes); int nbytes);
rt_err_t rt_usb_set_configure(uinst_t uinst, int config); rt_err_t rt_usb_set_configure(uinst_t uinst, int config);
rt_err_t rt_usb_set_address(uinst_t uinst); rt_err_t rt_usb_set_address(uinst_t uinst);
rt_err_t rt_usb_set_interface(uinst_t uinst, int intf); rt_err_t rt_usb_set_interface(uinst_t uinst, int intf);
rt_err_t rt_usb_clear_feature(uinst_t uinst, int endpoint, int feature); rt_err_t rt_usb_clear_feature(uinst_t uinst, int endpoint, int feature);
rt_err_t rt_usb_get_interface_descriptor(ucfg_desc_t cfg_desc, int num, rt_err_t rt_usb_get_interface_descriptor(ucfg_desc_t cfg_desc, int num,
uintf_desc_t* intf_desc); uintf_desc_t* intf_desc);
rt_err_t rt_usb_get_endpoint_descriptor(uintf_desc_t intf_desc, int num, rt_err_t rt_usb_get_endpoint_descriptor(uintf_desc_t intf_desc, int num,
uep_desc_t* ep_desc); uep_desc_t* ep_desc);
/* usb class driver interface */ /* usb class driver interface */
rt_err_t rt_usb_class_driver_init(void); rt_err_t rt_usb_class_driver_init(void);
...@@ -455,97 +455,97 @@ uprotocal_t rt_usb_hid_protocal_mouse(void); ...@@ -455,97 +455,97 @@ uprotocal_t rt_usb_hid_protocal_mouse(void);
/* usb hub interface */ /* usb hub interface */
rt_err_t rt_usb_hub_get_descriptor(uinst_t uinst, rt_uint8_t *buffer, rt_err_t rt_usb_hub_get_descriptor(uinst_t uinst, rt_uint8_t *buffer,
rt_size_t size); rt_size_t size);
rt_err_t rt_usb_hub_get_status(uinst_t uinst, rt_uint8_t* buffer); rt_err_t rt_usb_hub_get_status(uinst_t uinst, rt_uint8_t* buffer);
rt_err_t rt_usb_hub_get_port_status(uhubinst_t uhub, rt_uint16_t port, rt_err_t rt_usb_hub_get_port_status(uhubinst_t uhub, rt_uint16_t port,
rt_uint8_t* buffer); rt_uint8_t* buffer);
rt_err_t rt_usb_hub_clear_port_feature(uhubinst_t uhub, rt_uint16_t port, rt_err_t rt_usb_hub_clear_port_feature(uhubinst_t uhub, rt_uint16_t port,
rt_uint16_t feature); rt_uint16_t feature);
rt_err_t rt_usb_hub_set_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_uint16_t feature);
rt_err_t rt_usb_hub_reset_port(uhubinst_t uhub, rt_uint16_t port); 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 umsg* msg, rt_size_t size);
/* usb host controller driver interface */ /* usb host controller driver interface */
rt_inline rt_err_t rt_usb_hcd_alloc_pipe(uhcd_t hcd, upipe_t* pipe, rt_inline rt_err_t rt_usb_hcd_alloc_pipe(uhcd_t hcd, upipe_t* pipe,
uifinst_t ifinst, uep_desc_t ep, func_callback callback) uifinst_t ifinst, uep_desc_t ep, func_callback callback)
{ {
if(ifinst == RT_NULL) return -RT_EIO; if(ifinst == RT_NULL) return -RT_EIO;
/* parameter check */ /* parameter check */
RT_ASSERT(hcd != RT_NULL); RT_ASSERT(hcd != RT_NULL);
RT_ASSERT(hcd->ops != RT_NULL); RT_ASSERT(hcd->ops != RT_NULL);
RT_ASSERT(hcd->ops->alloc_pipe!= RT_NULL); RT_ASSERT(hcd->ops->alloc_pipe!= RT_NULL);
return hcd->ops->alloc_pipe(pipe, ifinst, ep, callback); return hcd->ops->alloc_pipe(pipe, ifinst, ep, callback);
} }
rt_inline rt_err_t rt_usb_hcd_free_pipe(uhcd_t hcd, upipe_t pipe) rt_inline rt_err_t rt_usb_hcd_free_pipe(uhcd_t hcd, upipe_t pipe)
{ {
RT_ASSERT(pipe != RT_NULL); RT_ASSERT(pipe != RT_NULL);
/* parameter check */ /* parameter check */
RT_ASSERT(hcd != RT_NULL); RT_ASSERT(hcd != RT_NULL);
RT_ASSERT(hcd->ops != RT_NULL); RT_ASSERT(hcd->ops != RT_NULL);
RT_ASSERT(hcd->ops->free_pipe!= RT_NULL); RT_ASSERT(hcd->ops->free_pipe!= RT_NULL);
return hcd->ops->free_pipe(pipe); return hcd->ops->free_pipe(pipe);
} }
rt_inline int rt_usb_hcd_bulk_xfer(uhcd_t hcd, upipe_t pipe, void* buffer, rt_inline int rt_usb_hcd_bulk_xfer(uhcd_t hcd, upipe_t pipe, void* buffer,
int nbytes, int timeout) int nbytes, int timeout)
{ {
if(pipe == RT_NULL) return -1; if(pipe == RT_NULL) return -1;
if(pipe->ifinst == RT_NULL) return -1; if(pipe->ifinst == RT_NULL) return -1;
if(pipe->ifinst->uinst == RT_NULL) return -1; if(pipe->ifinst->uinst == RT_NULL) return -1;
if(pipe->ifinst->uinst->status == UINST_STATUS_IDLE) if(pipe->ifinst->uinst->status == UINST_STATUS_IDLE)
return -1; return -1;
/* parameter check */ /* parameter check */
RT_ASSERT(hcd != RT_NULL); RT_ASSERT(hcd != RT_NULL);
RT_ASSERT(hcd->ops != RT_NULL); RT_ASSERT(hcd->ops != RT_NULL);
RT_ASSERT(hcd->ops->bulk_xfer!= RT_NULL); RT_ASSERT(hcd->ops->bulk_xfer!= RT_NULL);
return hcd->ops->bulk_xfer(pipe, buffer, nbytes, timeout); return hcd->ops->bulk_xfer(pipe, buffer, nbytes, timeout);
} }
rt_inline int rt_usb_hcd_control_xfer(uhcd_t hcd, uinst_t uinst, ureq_t setup, rt_inline int rt_usb_hcd_control_xfer(uhcd_t hcd, uinst_t uinst, ureq_t setup,
void* buffer, int nbytes, int timeout) void* buffer, int nbytes, int timeout)
{ {
if(uinst->status == UINST_STATUS_IDLE) return -1; if(uinst->status == UINST_STATUS_IDLE) return -1;
/* parameter check */ /* parameter check */
RT_ASSERT(hcd != RT_NULL); RT_ASSERT(hcd != RT_NULL);
RT_ASSERT(hcd->ops != RT_NULL); RT_ASSERT(hcd->ops != RT_NULL);
RT_ASSERT(hcd->ops->ctl_xfer!= RT_NULL); RT_ASSERT(hcd->ops->ctl_xfer!= RT_NULL);
return hcd->ops->ctl_xfer(uinst, setup, buffer, nbytes, timeout); return hcd->ops->ctl_xfer(uinst, setup, buffer, nbytes, timeout);
} }
rt_inline int rt_usb_hcd_int_xfer(uhcd_t hcd, upipe_t pipe, void* buffer, rt_inline int rt_usb_hcd_int_xfer(uhcd_t hcd, upipe_t pipe, void* buffer,
int nbytes, int timeout) int nbytes, int timeout)
{ {
if(pipe == RT_NULL) return -1; if(pipe == RT_NULL) return -1;
if(pipe->ifinst == RT_NULL) return -1; if(pipe->ifinst == RT_NULL) return -1;
if(pipe->ifinst->uinst == RT_NULL) return -1; if(pipe->ifinst->uinst == RT_NULL) return -1;
if(pipe->ifinst->uinst->status == UINST_STATUS_IDLE) if(pipe->ifinst->uinst->status == UINST_STATUS_IDLE)
return -1; return -1;
RT_ASSERT(hcd != RT_NULL); RT_ASSERT(hcd != RT_NULL);
RT_ASSERT(hcd->ops != RT_NULL); RT_ASSERT(hcd->ops != RT_NULL);
RT_ASSERT(hcd->ops->int_xfer!= RT_NULL); RT_ASSERT(hcd->ops->int_xfer!= RT_NULL);
return hcd->ops->int_xfer(pipe, buffer, nbytes, timeout); 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_inline rt_err_t rt_usb_hcd_hub_control(uhcd_t hcd, rt_uint16_t port,
rt_uint8_t cmd, void *args) rt_uint8_t cmd, void *args)
{ {
RT_ASSERT(hcd != RT_NULL); RT_ASSERT(hcd != RT_NULL);
RT_ASSERT(hcd->ops != RT_NULL); RT_ASSERT(hcd->ops != RT_NULL);
RT_ASSERT(hcd->ops->hub_ctrl != RT_NULL); RT_ASSERT(hcd->ops->hub_ctrl != RT_NULL);
return hcd->ops->hub_ctrl(port, cmd, args); return hcd->ops->hub_ctrl(port, cmd, args);
} }
#endif #endif
......
...@@ -17,10 +17,10 @@ if GetDepend('RT_USB_CLASS_MASS_STORAGE'): ...@@ -17,10 +17,10 @@ if GetDepend('RT_USB_CLASS_MASS_STORAGE'):
src += Glob('class/mass.c') src += Glob('class/mass.c')
src += Glob('udev/udisk.c') src += Glob('udev/udisk.c')
if GetDepend('RT_USING_CLASS_HID'): if GetDepend('RT_USB_CLASS_HID'):
src += Glob('class/hid.c') src += Glob('class/hid.c')
if GetDepend('RT_USING_HID_MOUSE'): if GetDepend('RT_USB_HID_MOUSE'):
src += Glob('udev/umouse.c') src += Glob('udev/umouse.c')
if GetDepend('RT_USB_HID_KEYBOARD'): if GetDepend('RT_USB_HID_KEYBOARD'):
......
...@@ -20,52 +20,157 @@ ...@@ -20,52 +20,157 @@
static struct uclass_driver adk_driver; static struct uclass_driver adk_driver;
rt_err_t rt_usb_adk_read(uifinst_t ifinst, rt_uint8_t *buffer, /**
rt_size_t size) * This function will do USB_REQ_GET_PROTOCOL request to set idle period to the usb adk device
*
* @param ifinst the interface instance.
* @duration the idle period of requesting data.
* @report_id the report id
*
* @return the error code, RT_EOK on successfully.
*/
rt_err_t rt_usb_adk_get_protocol(uifinst_t ifinst, rt_uint16_t *protocol)
{
struct ureqest setup;
uinst_t uinst;
int timeout = 100;
/* parameter check */
RT_ASSERT(ifinst != RT_NULL);
RT_ASSERT(ifinst->uinst != RT_NULL);
uinst = ifinst->uinst;
setup.request_type = USB_REQ_TYPE_DIR_IN | USB_REQ_TYPE_VENDOR |
USB_REQ_TYPE_DEVICE;
setup.request = USB_REQ_GET_PROTOCOL;
setup.index = 0;
setup.length = 2;
setup.value = 0;
if(rt_usb_hcd_control_xfer(uinst->hcd, uinst, &setup, (void*)protocol, 2,
timeout) == 0) return RT_EOK;
else return -RT_FALSE;
}
/**
* This function will do USB_REQ_SEND_STRING request to set idle period to the usb adk device
*
* @param ifinst the interface instance.
* @duration the idle period of requesting data.
* @report_id the report id
*
* @return the error code, RT_EOK on successfully.
*/
rt_err_t rt_usb_adk_send_string(uifinst_t ifinst, rt_uint16_t index,
const char* str)
{
struct ureqest setup;
uinst_t uinst;
int timeout = 100;
/* parameter check */
RT_ASSERT(ifinst != RT_NULL);
RT_ASSERT(ifinst->uinst != RT_NULL);
uinst = ifinst->uinst;
setup.request_type = USB_REQ_TYPE_DIR_OUT | USB_REQ_TYPE_VENDOR |
USB_REQ_TYPE_DEVICE;
setup.request = USB_REQ_SEND_STRING;
setup.index = index;
setup.length = rt_strlen(str) + 1;
setup.value = 0;
if(rt_usb_hcd_control_xfer(uinst->hcd, uinst, &setup, (void*)str,
rt_strlen(str) + 1, timeout) == 0) return RT_EOK;
else return -RT_FALSE;
}
/**
* This function will do USB_REQ_START request to set idle period to the usb adk device
*
* @param ifinst the interface instance.
* @duration the idle period of requesting data.
* @report_id the report id
*
* @return the error code, RT_EOK on successfully.
*/
rt_err_t rt_usb_adk_start(uifinst_t ifinst)
{
struct ureqest setup;
uinst_t uinst;
int timeout = 100;
/* parameter check */
RT_ASSERT(ifinst != RT_NULL);
RT_ASSERT(ifinst->uinst != RT_NULL);
uinst = ifinst->uinst;
setup.request_type = USB_REQ_TYPE_DIR_OUT | USB_REQ_TYPE_VENDOR |
USB_REQ_TYPE_DEVICE;
setup.request = USB_REQ_START;
setup.index = 0;
setup.length = 0;
setup.value = 0;
if(rt_usb_hcd_control_xfer(uinst->hcd, uinst, &setup, RT_NULL, 0,
timeout) == 0) return RT_EOK;
else return -RT_FALSE;
}
/**
* This function will read data from usb adk device
*
* @param ifinst the interface instance.
*
* @return the error code, RT_EOK on successfully.
*/
static rt_size_t rt_usb_adk_read(rt_device_t device, rt_off_t pos, void* buffer,
rt_size_t size)
{ {
uadkinst_t adkinst; uadkinst_t adkinst;
rt_size_t length; rt_size_t length;
uifinst_t ifinst;
RT_ASSERT(buffer != RT_NULL);
/* check parameter */
if(ifinst == RT_NULL) RT_ASSERT(device != RT_NULL);
{ RT_ASSERT(buffer != RT_NULL);
rt_kprintf("the interface is not available\n");
return -RT_EIO; ifinst = (uifinst_t)device->user_data;
} adkinst = (uadkinst_t)ifinst->user_data;
/* get storage instance from the interface instance */ length = rt_usb_hcd_bulk_xfer(ifinst->uinst->hcd, adkinst->pipe_in,
adkinst = (uadkinst_t)ifinst->user_data; buffer, size, 300);
/* send the cbw */ return length;
length = rt_usb_hcd_bulk_xfer(ifinst->uinst->hcd, adkinst->pipe_in,
buffer, size, 300);
return length;
} }
rt_err_t rt_usb_adk_write(uifinst_t ifinst, rt_uint8_t *buffer, /**
rt_size_t size) * This function will write data to usb adk device
*
* @param ifinst the interface instance.
*
* @return the error code, RT_EOK on successfully.
*/
static rt_size_t rt_usb_adk_write (rt_device_t device, rt_off_t pos, const void* buffer,
rt_size_t size)
{ {
uadkinst_t adkinst; uadkinst_t adkinst;
rt_size_t length; rt_size_t length;
uifinst_t ifinst;
RT_ASSERT(buffer != RT_NULL);
RT_ASSERT(buffer != RT_NULL);
if(ifinst == RT_NULL)
{ ifinst = (uifinst_t)device->user_data;
rt_kprintf("the interface is not available\n"); adkinst = (uadkinst_t)ifinst->user_data;
return -RT_EIO;
} length = rt_usb_hcd_bulk_xfer(ifinst->uinst->hcd, adkinst->pipe_out,
(void*)buffer, size, 300);
/* get storage instance from the interface instance */
adkinst = (uadkinst_t)ifinst->user_data; return length;
/* send the cbw */
length = rt_usb_hcd_bulk_xfer(ifinst->uinst->hcd, adkinst->pipe_out,
buffer, size, 300);
return length;
} }
/** /**
...@@ -78,68 +183,127 @@ rt_err_t rt_usb_adk_write(uifinst_t ifinst, rt_uint8_t *buffer, ...@@ -78,68 +183,127 @@ rt_err_t rt_usb_adk_write(uifinst_t ifinst, rt_uint8_t *buffer,
*/ */
static rt_err_t rt_usb_adk_run(void* arg) static rt_err_t rt_usb_adk_run(void* arg)
{ {
int i = 0; int i = 0;
uadkinst_t adkinst; uadkinst_t adkinst;
uifinst_t ifinst = (uifinst_t)arg; uifinst_t ifinst = (uifinst_t)arg;
rt_err_t ret; udev_desc_t dev_desc;
rt_uint16_t protocol;
/* parameter check */ rt_err_t ret;
if(ifinst == RT_NULL)
{ /* parameter check */
rt_kprintf("the interface is not available\n"); if(ifinst == RT_NULL)
return -RT_EIO; {
} rt_kprintf("the interface is not available\n");
return -RT_EIO;
RT_DEBUG_LOG(RT_DEBUG_USB,("rt_usb_adk_run\n")); }
adkinst = rt_malloc(sizeof(struct uadkinst)); RT_DEBUG_LOG(RT_DEBUG_USB,("rt_usb_adk_run\n"));
RT_ASSERT(adkinst != RT_NULL);
if(ifinst->intf_desc->bInterfaceSubClass != 0xFF) return -RT_ERROR;
/* initilize the data structure */
rt_memset(adkinst, 0, sizeof(struct uadkinst)); dev_desc = &ifinst->uinst->dev_desc;
ifinst->user_data = (void*)adkinst; if(dev_desc->idVendor == USB_ACCESSORY_VENDOR_ID &&
(dev_desc->idProduct == USB_ACCESSORY_PRODUCT_ID ||
for(i=0; i<ifinst->intf_desc->bNumEndpoints; i++) dev_desc->idProduct == USB_ACCESSORY_ADB_PRODUCT_ID))
{ {
uep_desc_t ep_desc; rt_kprintf("found android accessory device\n");
}
/* get endpoint descriptor from interface descriptor */ else
rt_usb_get_endpoint_descriptor(ifinst->intf_desc, i, &ep_desc); {
if(ep_desc == RT_NULL) rt_kprintf("switch device\n");
{
rt_kprintf("rt_usb_get_endpoint_descriptor error\n"); if((ret = rt_usb_adk_get_protocol(ifinst, &protocol)) != RT_EOK)
return -RT_ERROR; {
} rt_kprintf("rt_usb_adk_get_protocol failed\n");
return ret;
/* the endpoint type of adk class should be BULK */ }
if((ep_desc->bmAttributes & USB_EP_ATTR_TYPE_MASK) != USB_EP_ATTR_BULK)
continue; if(protocol != 1)
{
/* allocate pipes according to the endpoint type */ rt_kprintf("read protocol failed\n");
if(ep_desc->bEndpointAddress & USB_DIR_IN) return -RT_ERROR;
{ }
/* allocate an in pipe for the adk instance */
ret = rt_usb_hcd_alloc_pipe(ifinst->uinst->hcd, &adkinst->pipe_in, rt_usb_adk_send_string(ifinst, ACCESSORY_STRING_MANUFACTURER, "Real Thread, Inc");
ifinst, ep_desc, RT_NULL); rt_usb_adk_send_string(ifinst, ACCESSORY_STRING_MODEL, "ART");
if(ret != RT_EOK) return ret; rt_usb_adk_send_string(ifinst, ACCESSORY_STRING_DESCRIPTION, "Arduino like board");
} rt_usb_adk_send_string(ifinst, ACCESSORY_STRING_VERSION, "1.0");
else rt_usb_adk_send_string(ifinst, ACCESSORY_STRING_VERSION, "www.rt-thread.org");
{ rt_usb_adk_send_string(ifinst, ACCESSORY_STRING_SERIAL, "00000012345678");
/* allocate an output pipe for the adk instance */
ret = rt_usb_hcd_alloc_pipe(ifinst->uinst->hcd, &adkinst->pipe_out, if((ret = rt_usb_adk_start(ifinst)) != RT_EOK)
ifinst, ep_desc, RT_NULL); {
if(ret != RT_EOK) return ret; rt_kprintf("rt_usb_adk_start failed\n");
} return ret;
} }
/* check pipes infomation */ return RT_EOK;
if(adkinst->pipe_in == RT_NULL || adkinst->pipe_out == RT_NULL) }
{
rt_kprintf("pipe error, unsupported device\n"); adkinst = rt_malloc(sizeof(struct uadkinst));
return -RT_ERROR; RT_ASSERT(adkinst != RT_NULL);
}
/* initilize the data structure */
return RT_EOK; rt_memset(adkinst, 0, sizeof(struct uadkinst));
ifinst->user_data = (void*)adkinst;
for(i=0; i<ifinst->intf_desc->bNumEndpoints; i++)
{
uep_desc_t ep_desc;
/* get endpoint descriptor from interface descriptor */
rt_usb_get_endpoint_descriptor(ifinst->intf_desc, i, &ep_desc);
if(ep_desc == RT_NULL)
{
rt_kprintf("rt_usb_get_endpoint_descriptor error\n");
return -RT_ERROR;
}
/* the endpoint type of adk class should be BULK */
if((ep_desc->bmAttributes & USB_EP_ATTR_TYPE_MASK) != USB_EP_ATTR_BULK)
continue;
/* allocate pipes according to the endpoint type */
if(ep_desc->bEndpointAddress & USB_DIR_IN)
{
/* allocate an in pipe for the adk instance */
ret = rt_usb_hcd_alloc_pipe(ifinst->uinst->hcd, &adkinst->pipe_in,
ifinst, ep_desc, RT_NULL);
if(ret != RT_EOK) return ret;
}
else
{
/* allocate an output pipe for the adk instance */
ret = rt_usb_hcd_alloc_pipe(ifinst->uinst->hcd, &adkinst->pipe_out,
ifinst, ep_desc, RT_NULL);
if(ret != RT_EOK) return ret;
}
}
/* check pipes infomation */
if(adkinst->pipe_in == RT_NULL || adkinst->pipe_out == RT_NULL)
{
rt_kprintf("pipe error, unsupported device\n");
return -RT_ERROR;
}
/* set configuration */
ret = rt_usb_set_configure(ifinst->uinst, 1);
if(ret != RT_EOK) return ret;
/* register adk device */
adkinst->device.type = RT_Device_Class_Char;
adkinst->device.init = RT_NULL;
adkinst->device.open = RT_NULL;
adkinst->device.close = RT_NULL;
adkinst->device.read = rt_usb_adk_read;
adkinst->device.write = rt_usb_adk_write;
adkinst->device.control = RT_NULL;
adkinst->device.user_data = (void*)ifinst;
rt_device_register(&adkinst->device, "adkdev", RT_DEVICE_FLAG_RDWR);
return RT_EOK;
} }
/** /**
...@@ -152,25 +316,36 @@ static rt_err_t rt_usb_adk_run(void* arg) ...@@ -152,25 +316,36 @@ static rt_err_t rt_usb_adk_run(void* arg)
*/ */
static rt_err_t rt_usb_adk_stop(void* arg) static rt_err_t rt_usb_adk_stop(void* arg)
{ {
uadkinst_t adkinst; uadkinst_t adkinst;
uifinst_t ifinst = (uifinst_t)arg; uifinst_t ifinst = (uifinst_t)arg;
RT_ASSERT(ifinst != RT_NULL);
RT_ASSERT(ifinst != RT_NULL); RT_DEBUG_LOG(RT_DEBUG_USB, ("rt_usb_adk_stop\n"));
RT_DEBUG_LOG(RT_DEBUG_USB, ("rt_usb_adk_stop\n")); adkinst = (uadkinst_t)ifinst->user_data;
if(adkinst == RT_NULL)
{
rt_free(ifinst);
return RT_EOK;
}
if(adkinst->pipe_in != RT_NULL)
rt_usb_hcd_free_pipe(ifinst->uinst->hcd, adkinst->pipe_in);
adkinst = (uadkinst_t)ifinst->user_data; if(adkinst->pipe_out != RT_NULL)
rt_usb_hcd_free_pipe(ifinst->uinst->hcd, adkinst->pipe_out);
if(adkinst->pipe_in != RT_NULL) /* unregister adk device */
rt_usb_hcd_free_pipe(ifinst->uinst->hcd, adkinst->pipe_in); rt_device_unregister(&adkinst->device);
/* free adk instance */ /* free adk instance */
if(adkinst != RT_NULL) rt_free(adkinst); if(adkinst != RT_NULL) rt_free(adkinst);
/* free interface instance */ /* free interface instance */
if(ifinst != RT_NULL) rt_free(ifinst); rt_free(ifinst);
return RT_EOK; return RT_EOK;
} }
/** /**
...@@ -181,12 +356,12 @@ static rt_err_t rt_usb_adk_stop(void* arg) ...@@ -181,12 +356,12 @@ static rt_err_t rt_usb_adk_stop(void* arg)
*/ */
ucd_t rt_usb_class_driver_adk(void) ucd_t rt_usb_class_driver_adk(void)
{ {
adk_driver.class_code = USB_CLASS_ADK; adk_driver.class_code = USB_CLASS_ADK;
adk_driver.run = rt_usb_adk_run; adk_driver.run = rt_usb_adk_run;
adk_driver.stop = rt_usb_adk_stop; adk_driver.stop = rt_usb_adk_stop;
return &adk_driver; return &adk_driver;
} }
#endif #endif
......
...@@ -19,12 +19,29 @@ ...@@ -19,12 +19,29 @@
struct uadkinst struct uadkinst
{ {
upipe_t pipe_in; upipe_t pipe_in;
upipe_t pipe_out; upipe_t pipe_out;
};
struct rt_device device;
};
typedef struct uadkinst* uadkinst_t; typedef struct uadkinst* uadkinst_t;
#define USB_CLASS_ADK 0xff #define USB_ACCESSORY_VENDOR_ID 0x18D1
#define USB_ACCESSORY_PRODUCT_ID 0x2D00
#define USB_ACCESSORY_ADB_PRODUCT_ID 0x2D01
#define ACCESSORY_STRING_MANUFACTURER 0
#define ACCESSORY_STRING_MODEL 1
#define ACCESSORY_STRING_DESCRIPTION 2
#define ACCESSORY_STRING_VERSION 3
#define ACCESSORY_STRING_URI 4
#define ACCESSORY_STRING_SERIAL 5
#define USB_REQ_GET_PROTOCOL 51
#define USB_REQ_SEND_STRING 52
#define USB_REQ_START 53
#define USB_CLASS_ADK 0xff
#endif #endif
...@@ -27,33 +27,33 @@ static struct uinstance uinst[USB_MAX_DEVICE]; ...@@ -27,33 +27,33 @@ static struct uinstance uinst[USB_MAX_DEVICE];
*/ */
uinst_t rt_usb_alloc_instance(void) uinst_t rt_usb_alloc_instance(void)
{ {
int i; int i;
/* lock scheduler */ /* lock scheduler */
rt_enter_critical(); rt_enter_critical();
for(i=0; i<USB_MAX_DEVICE; i++) for(i=0; i<USB_MAX_DEVICE; i++)
{ {
/* to find an idle instance handle */ /* to find an idle instance handle */
if(uinst[i].status != UINST_STATUS_IDLE) continue; if(uinst[i].status != UINST_STATUS_IDLE) continue;
/* initialize the usb device instance */ /* initialize the usb device instance */
rt_memset(&uinst[i], 0, sizeof(struct uinstance)); rt_memset(&uinst[i], 0, sizeof(struct uinstance));
uinst[i].status = UINST_STATUS_BUSY; uinst[i].status = UINST_STATUS_BUSY;
uinst[i].index = i + 1; uinst[i].index = i + 1;
uinst[i].address = 0; uinst[i].address = 0;
uinst[i].max_packet_size = 0x8; uinst[i].max_packet_size = 0x8;
/* unlock scheduler */ /* unlock scheduler */
rt_exit_critical(); rt_exit_critical();
return &uinst[i]; return &uinst[i];
} }
/* unlock scheduler */ /* unlock scheduler */
rt_exit_critical(); rt_exit_critical();
return RT_NULL; return RT_NULL;
} }
/** /**
...@@ -67,113 +67,123 @@ uinst_t rt_usb_alloc_instance(void) ...@@ -67,113 +67,123 @@ uinst_t rt_usb_alloc_instance(void)
*/ */
rt_err_t rt_usb_attatch_instance(uinst_t uinst) rt_err_t rt_usb_attatch_instance(uinst_t uinst)
{ {
int i = 0; int i = 0;
rt_err_t ret = RT_EOK; rt_err_t ret = RT_EOK;
struct uconfig_descriptor cfg_desc; struct uconfig_descriptor cfg_desc;
udev_desc_t dev_desc; udev_desc_t dev_desc;
uintf_desc_t intf_desc; uintf_desc_t intf_desc;
ucd_t drv; ucd_t drv;
RT_ASSERT(uinst != RT_NULL); RT_ASSERT(uinst != RT_NULL);
rt_memset(&cfg_desc, 0, sizeof(struct uconfig_descriptor)); rt_memset(&cfg_desc, 0, sizeof(struct uconfig_descriptor));
dev_desc = &uinst->dev_desc; dev_desc = &uinst->dev_desc;
/* get device descriptor head */ RT_DEBUG_LOG(RT_DEBUG_USB, ("start enumnation\n"));
ret = rt_usb_get_descriptor(uinst, USB_DESC_TYPE_DEVICE, (void*)dev_desc, 8);
if(ret != RT_EOK) /* get device descriptor head */
{ ret = rt_usb_get_descriptor(uinst, USB_DESC_TYPE_DEVICE, (void*)dev_desc, 8);
rt_kprintf("get device descriptor head failed\n"); if(ret != RT_EOK)
return ret; {
} rt_kprintf("get device descriptor head failed\n");
return ret;
/* set device address */ }
ret = rt_usb_set_address(uinst);
if(ret != RT_EOK) /* set device address */
{ ret = rt_usb_set_address(uinst);
rt_kprintf("set device address failed\n"); if(ret != RT_EOK)
return ret; {
} rt_kprintf("set device address failed\n");
return ret;
/* set device max packet size */ }
uinst->max_packet_size = uinst->dev_desc.bMaxPacketSize0;
/* set device max packet size */
RT_DEBUG_LOG(RT_DEBUG_USB, ("get device descriptor length %d\n", uinst->max_packet_size = uinst->dev_desc.bMaxPacketSize0;
dev_desc->bLength));
RT_DEBUG_LOG(RT_DEBUG_USB, ("get device descriptor length %d\n",
/* get full device descriptor again */ dev_desc->bLength));
ret = rt_usb_get_descriptor
(uinst, USB_DESC_TYPE_DEVICE, (void*)dev_desc, dev_desc->bLength); /* get full device descriptor again */
if(ret != RT_EOK) ret = rt_usb_get_descriptor
{ (uinst, USB_DESC_TYPE_DEVICE, (void*)dev_desc, dev_desc->bLength);
rt_kprintf("get full device descriptor failed\n"); if(ret != RT_EOK)
return ret; {
} rt_kprintf("get full device descriptor failed\n");
return ret;
/* get configuration descriptor head */ }
ret = rt_usb_get_descriptor(uinst, USB_DESC_TYPE_CONFIGURATION, &cfg_desc,
sizeof(struct uconfig_descriptor)); RT_DEBUG_LOG(RT_DEBUG_USB, ("Vendor ID 0x%x\n", dev_desc->idVendor));
if(ret != RT_EOK) RT_DEBUG_LOG(RT_DEBUG_USB, ("Product ID 0x%x\n", dev_desc->idProduct));
{
rt_kprintf("get configuration descriptor head failed\n"); /* get configuration descriptor head */
return ret; ret = rt_usb_get_descriptor(uinst, USB_DESC_TYPE_CONFIGURATION, &cfg_desc,
} sizeof(struct uconfig_descriptor));
if(ret != RT_EOK)
/* alloc memory for configuration descriptor */ {
uinst->cfg_desc = (ucfg_desc_t)rt_malloc(cfg_desc.wTotalLength); rt_kprintf("get configuration descriptor head failed\n");
rt_memset(uinst->cfg_desc, 0, cfg_desc.wTotalLength); return ret;
}
/* get full configuration descriptor */
ret = rt_usb_get_descriptor(uinst, USB_DESC_TYPE_CONFIGURATION, /* alloc memory for configuration descriptor */
uinst->cfg_desc, cfg_desc.wTotalLength); uinst->cfg_desc = (ucfg_desc_t)rt_malloc(cfg_desc.wTotalLength);
if(ret != RT_EOK) rt_memset(uinst->cfg_desc, 0, cfg_desc.wTotalLength);
{
rt_kprintf("get full configuration descriptor failed\n"); /* get full configuration descriptor */
return ret; ret = rt_usb_get_descriptor(uinst, USB_DESC_TYPE_CONFIGURATION,
} uinst->cfg_desc, cfg_desc.wTotalLength);
if(ret != RT_EOK)
/* set configuration */ {
ret = rt_usb_set_configure(uinst, 1); rt_kprintf("get full configuration descriptor failed\n");
if(ret != RT_EOK) return ret; return ret;
}
//for(i=0; i<uinst->cfg_desc->bNumInterfaces; i++)
{ /* set configuration */
/* get interface descriptor through configuration descriptor */ ret = rt_usb_set_configure(uinst, 1);
ret = rt_usb_get_interface_descriptor(uinst->cfg_desc, i, &intf_desc); if(ret != RT_EOK) return ret;
if(ret != RT_EOK)
{ for(i=0; i<uinst->cfg_desc->bNumInterfaces; i++)
rt_kprintf("rt_usb_get_interface_descriptor error\n"); {
return -RT_ERROR; /* get interface descriptor through configuration descriptor */
} ret = rt_usb_get_interface_descriptor(uinst->cfg_desc, i, &intf_desc);
if(ret != RT_EOK)
/* find driver by class code found in interface descriptor */ {
drv = rt_usb_class_driver_find(intf_desc->bInterfaceClass, rt_kprintf("rt_usb_get_interface_descriptor error\n");
intf_desc->bInterfaceSubClass); return -RT_ERROR;
if(drv != RT_NULL) }
{
/* allocate memory for interface uinst */ RT_DEBUG_LOG(RT_DEBUG_USB, ("interface class 0x%x, subclass 0x%x\n",
uinst->ifinst[i] = intf_desc->bInterfaceClass, intf_desc->bInterfaceSubClass));
(uifinst_t)rt_malloc(sizeof(struct uifinst));
/* find driver by class code found in interface descriptor */
uinst->ifinst[i]->drv = drv; drv = rt_usb_class_driver_find(intf_desc->bInterfaceClass,
uinst->ifinst[i]->uinst = uinst; intf_desc->bInterfaceSubClass);
uinst->ifinst[i]->intf_desc = intf_desc;
if(drv != RT_NULL)
/* open usb class driver */ {
ret = rt_usb_class_driver_run(drv, (void*)uinst->ifinst[i]); /* allocate memory for interface uinst */
if(ret != RT_EOK) uinst->ifinst[i] =
{ (uifinst_t)rt_malloc(sizeof(struct uifinst));
rt_kprintf("interface %d run class driver error\n", i);
} uinst->ifinst[i]->drv = drv;
} uinst->ifinst[i]->uinst = uinst;
else uinst->ifinst[i]->intf_desc = intf_desc;
{ uinst->ifinst[i]->user_data = RT_NULL;
rt_kprintf("find usb device driver failed\n");
return -RT_ERROR; /* open usb class driver */
} ret = rt_usb_class_driver_run(drv, (void*)uinst->ifinst[i]);
} if(ret != RT_EOK)
{
return RT_EOK; rt_kprintf("interface %d run class driver error\n", i);
}
}
else
{
rt_kprintf("find usb device driver failed\n");
continue;
}
}
return RT_EOK;
} }
/** /**
...@@ -186,31 +196,31 @@ rt_err_t rt_usb_attatch_instance(uinst_t uinst) ...@@ -186,31 +196,31 @@ rt_err_t rt_usb_attatch_instance(uinst_t uinst)
*/ */
rt_err_t rt_usb_detach_instance(uinst_t uinst) rt_err_t rt_usb_detach_instance(uinst_t uinst)
{ {
int i = 0; int i = 0;
if(uinst == RT_NULL) if(uinst == RT_NULL)
{ {
rt_kprintf("no usb instance to detach\n"); rt_kprintf("no usb instance to detach\n");
return -RT_ERROR; return -RT_ERROR;
} }
/* free configration descriptor */ /* free configration descriptor */
if(uinst->cfg_desc) rt_free(uinst->cfg_desc); if(uinst->cfg_desc) rt_free(uinst->cfg_desc);
for(i=0; i<uinst->cfg_desc->bNumInterfaces; i++) for(i=0; i<uinst->cfg_desc->bNumInterfaces; i++)
{ {
if(uinst->ifinst[i] == RT_NULL) continue; if(uinst->ifinst[i] == RT_NULL) continue;
if(uinst->ifinst[i]->drv == RT_NULL) continue; if(uinst->ifinst[i]->drv == RT_NULL) continue;
RT_ASSERT(uinst->ifinst[i]->uinst == uinst); RT_ASSERT(uinst->ifinst[i]->uinst == uinst);
RT_DEBUG_LOG(RT_DEBUG_USB, ("free interface instance %d\n", i)); RT_DEBUG_LOG(RT_DEBUG_USB, ("free interface instance %d\n", i));
rt_usb_class_driver_stop(uinst->ifinst[i]->drv, (void*)uinst->ifinst[i]); rt_usb_class_driver_stop(uinst->ifinst[i]->drv, (void*)uinst->ifinst[i]);
} }
rt_memset(uinst, 0, sizeof(struct uinstance)); rt_memset(uinst, 0, sizeof(struct uinstance));
return RT_EOK; return RT_EOK;
} }
/** /**
...@@ -224,23 +234,23 @@ rt_err_t rt_usb_detach_instance(uinst_t uinst) ...@@ -224,23 +234,23 @@ rt_err_t rt_usb_detach_instance(uinst_t uinst)
* @return the error code, RT_EOK on successfully. * @return the error code, RT_EOK on successfully.
*/ */
rt_err_t rt_usb_get_descriptor(uinst_t uinst, rt_uint8_t type, void* buffer, rt_err_t rt_usb_get_descriptor(uinst_t uinst, rt_uint8_t type, void* buffer,
int nbytes) int nbytes)
{ {
struct ureqest setup; struct ureqest setup;
int timeout = 100; int timeout = 100;
RT_ASSERT(uinst != RT_NULL); RT_ASSERT(uinst != RT_NULL);
setup.request_type = USB_REQ_TYPE_DIR_IN | USB_REQ_TYPE_STANDARD | setup.request_type = USB_REQ_TYPE_DIR_IN | USB_REQ_TYPE_STANDARD |
USB_REQ_TYPE_DEVICE; USB_REQ_TYPE_DEVICE;
setup.request = USB_REQ_GET_DESCRIPTOR; setup.request = USB_REQ_GET_DESCRIPTOR;
setup.index = 0; setup.index = 0;
setup.length = nbytes; setup.length = nbytes;
setup.value = type << 8; setup.value = type << 8;
if(rt_usb_hcd_control_xfer(uinst->hcd, uinst, &setup, buffer, nbytes, if(rt_usb_hcd_control_xfer(uinst->hcd, uinst, &setup, buffer, nbytes,
timeout) != nbytes) return -RT_EIO; timeout) != nbytes) return -RT_EIO;
else return RT_EOK; else return RT_EOK;
} }
/** /**
...@@ -252,28 +262,28 @@ rt_err_t rt_usb_get_descriptor(uinst_t uinst, rt_uint8_t type, void* buffer, ...@@ -252,28 +262,28 @@ rt_err_t rt_usb_get_descriptor(uinst_t uinst, rt_uint8_t type, void* buffer,
*/ */
rt_err_t rt_usb_set_address(uinst_t uinst) rt_err_t rt_usb_set_address(uinst_t uinst)
{ {
struct ureqest setup; struct ureqest setup;
int timeout = 100; int timeout = 100;
RT_ASSERT(uinst != RT_NULL); RT_ASSERT(uinst != RT_NULL);
RT_DEBUG_LOG(RT_DEBUG_USB, ("rt_usb_set_address\n")); RT_DEBUG_LOG(RT_DEBUG_USB, ("rt_usb_set_address\n"));
setup.request_type = USB_REQ_TYPE_DIR_OUT | USB_REQ_TYPE_STANDARD | setup.request_type = USB_REQ_TYPE_DIR_OUT | USB_REQ_TYPE_STANDARD |
USB_REQ_TYPE_DEVICE; USB_REQ_TYPE_DEVICE;
setup.request = USB_REQ_SET_ADDRESS; setup.request = USB_REQ_SET_ADDRESS;
setup.index = 0; setup.index = 0;
setup.length = 0; setup.length = 0;
setup.value = uinst->index; setup.value = uinst->index;
if(rt_usb_hcd_control_xfer(uinst->hcd, uinst, &setup, RT_NULL, 0, if(rt_usb_hcd_control_xfer(uinst->hcd, uinst, &setup, RT_NULL, 0,
timeout) != 0) return -RT_EIO; timeout) != 0) return -RT_EIO;
rt_thread_delay(50); rt_thread_delay(50);
uinst->address = uinst->index; uinst->address = uinst->index;
return RT_EOK; return RT_EOK;
} }
/** /**
...@@ -286,23 +296,23 @@ rt_err_t rt_usb_set_address(uinst_t uinst) ...@@ -286,23 +296,23 @@ rt_err_t rt_usb_set_address(uinst_t uinst)
*/ */
rt_err_t rt_usb_set_configure(uinst_t uinst, int config) rt_err_t rt_usb_set_configure(uinst_t uinst, int config)
{ {
struct ureqest setup; struct ureqest setup;
int timeout = 100; int timeout = 100;
/* check parameter */ /* check parameter */
RT_ASSERT(uinst != RT_NULL); RT_ASSERT(uinst != RT_NULL);
setup.request_type = USB_REQ_TYPE_DIR_OUT | USB_REQ_TYPE_STANDARD | setup.request_type = USB_REQ_TYPE_DIR_OUT | USB_REQ_TYPE_STANDARD |
USB_REQ_TYPE_DEVICE; USB_REQ_TYPE_DEVICE;
setup.request = USB_REQ_SET_CONFIGURATION; setup.request = USB_REQ_SET_CONFIGURATION;
setup.index = 0; setup.index = 0;
setup.length = 0; setup.length = 0;
setup.value = config; setup.value = config;
if(rt_usb_hcd_control_xfer(uinst->hcd, uinst, &setup, RT_NULL, 0, if(rt_usb_hcd_control_xfer(uinst->hcd, uinst, &setup, RT_NULL, 0,
timeout) != 0) return -RT_EIO; timeout) != 0) return -RT_EIO;
return RT_EOK; return RT_EOK;
} }
/** /**
...@@ -315,23 +325,23 @@ rt_err_t rt_usb_set_configure(uinst_t uinst, int config) ...@@ -315,23 +325,23 @@ rt_err_t rt_usb_set_configure(uinst_t uinst, int config)
*/ */
rt_err_t rt_usb_set_interface(uinst_t uinst, int intf) rt_err_t rt_usb_set_interface(uinst_t uinst, int intf)
{ {
struct ureqest setup; struct ureqest setup;
int timeout = 100; int timeout = 100;
/* check parameter */ /* check parameter */
RT_ASSERT(uinst != RT_NULL); RT_ASSERT(uinst != RT_NULL);
setup.request_type = USB_REQ_TYPE_DIR_OUT | USB_REQ_TYPE_STANDARD | setup.request_type = USB_REQ_TYPE_DIR_OUT | USB_REQ_TYPE_STANDARD |
USB_REQ_TYPE_INTERFACE; USB_REQ_TYPE_INTERFACE;
setup.request = USB_REQ_SET_INTERFACE; setup.request = USB_REQ_SET_INTERFACE;
setup.index = 0; setup.index = 0;
setup.length = 0; setup.length = 0;
setup.value = intf; setup.value = intf;
if(rt_usb_hcd_control_xfer(uinst->hcd, uinst, &setup, RT_NULL, 0, if(rt_usb_hcd_control_xfer(uinst->hcd, uinst, &setup, RT_NULL, 0,
timeout) != 0) return -RT_EIO; timeout) != 0) return -RT_EIO;
return RT_EOK; return RT_EOK;
} }
/** /**
...@@ -344,23 +354,23 @@ rt_err_t rt_usb_set_interface(uinst_t uinst, int intf) ...@@ -344,23 +354,23 @@ rt_err_t rt_usb_set_interface(uinst_t uinst, int intf)
*/ */
rt_err_t rt_usb_clear_feature(uinst_t uinst, int endpoint, int feature) rt_err_t rt_usb_clear_feature(uinst_t uinst, int endpoint, int feature)
{ {
struct ureqest setup; struct ureqest setup;
int timeout = 100; int timeout = 100;
/* check parameter */ /* check parameter */
RT_ASSERT(uinst != RT_NULL); RT_ASSERT(uinst != RT_NULL);
setup.request_type = USB_REQ_TYPE_DIR_OUT | USB_REQ_TYPE_STANDARD | setup.request_type = USB_REQ_TYPE_DIR_OUT | USB_REQ_TYPE_STANDARD |
USB_REQ_TYPE_ENDPOINT; USB_REQ_TYPE_ENDPOINT;
setup.request = USB_REQ_CLEAR_FEATURE; setup.request = USB_REQ_CLEAR_FEATURE;
setup.index = endpoint; setup.index = endpoint;
setup.length = 0; setup.length = 0;
setup.value = feature; setup.value = feature;
if(rt_usb_hcd_control_xfer(uinst->hcd, uinst, &setup, RT_NULL, 0, if(rt_usb_hcd_control_xfer(uinst->hcd, uinst, &setup, RT_NULL, 0,
timeout) != 0) return -RT_EIO; timeout) != 0) return -RT_EIO;
return RT_EOK; return RT_EOK;
} }
/** /**
...@@ -373,39 +383,39 @@ rt_err_t rt_usb_clear_feature(uinst_t uinst, int endpoint, int feature) ...@@ -373,39 +383,39 @@ rt_err_t rt_usb_clear_feature(uinst_t uinst, int endpoint, int feature)
* @return the error code, RT_EOK on successfully. * @return the error code, RT_EOK on successfully.
*/ */
rt_err_t rt_usb_get_interface_descriptor(ucfg_desc_t cfg_desc, int num, rt_err_t rt_usb_get_interface_descriptor(ucfg_desc_t cfg_desc, int num,
uintf_desc_t* intf_desc) uintf_desc_t* intf_desc)
{ {
rt_uint32_t ptr, depth = 0; rt_uint32_t ptr, depth = 0;
udesc_t desc; udesc_t desc;
/* check parameter */ /* check parameter */
RT_ASSERT(cfg_desc != RT_NULL); RT_ASSERT(cfg_desc != RT_NULL);
ptr = (rt_uint32_t)cfg_desc + cfg_desc->bLength; ptr = (rt_uint32_t)cfg_desc + cfg_desc->bLength;
while(ptr < (rt_uint32_t)cfg_desc + cfg_desc->wTotalLength) while(ptr < (rt_uint32_t)cfg_desc + cfg_desc->wTotalLength)
{ {
if(depth++ > 0x20) if(depth++ > 0x20)
{ {
*intf_desc = RT_NULL; *intf_desc = RT_NULL;
return -RT_EIO; return -RT_EIO;
} }
desc = (udesc_t)ptr; desc = (udesc_t)ptr;
if(desc->type == USB_DESC_TYPE_INTERFACE) if(desc->type == USB_DESC_TYPE_INTERFACE)
{ {
if(((uintf_desc_t)desc)->bInterfaceNumber == num) if(((uintf_desc_t)desc)->bInterfaceNumber == num)
{ {
*intf_desc = (uintf_desc_t)desc; *intf_desc = (uintf_desc_t)desc;
RT_DEBUG_LOG(RT_DEBUG_USB, RT_DEBUG_LOG(RT_DEBUG_USB,
("rt_usb_get_interface_descriptor: %d\n", num)); ("rt_usb_get_interface_descriptor: %d\n", num));
return RT_EOK; return RT_EOK;
} }
} }
ptr = (rt_uint32_t)desc + desc->bLength; ptr = (rt_uint32_t)desc + desc->bLength;
} }
rt_kprintf("rt_usb_get_interface_descriptor %d failed\n", num); rt_kprintf("rt_usb_get_interface_descriptor %d failed\n", num);
return -RT_EIO; return -RT_EIO;
} }
/** /**
...@@ -418,41 +428,41 @@ rt_err_t rt_usb_get_interface_descriptor(ucfg_desc_t cfg_desc, int num, ...@@ -418,41 +428,41 @@ rt_err_t rt_usb_get_interface_descriptor(ucfg_desc_t cfg_desc, int num,
* @return the error code, RT_EOK on successfully. * @return the error code, RT_EOK on successfully.
*/ */
rt_err_t rt_usb_get_endpoint_descriptor(uintf_desc_t intf_desc, int num, rt_err_t rt_usb_get_endpoint_descriptor(uintf_desc_t intf_desc, int num,
uep_desc_t* ep_desc) uep_desc_t* ep_desc)
{ {
int count = 0, depth = 0; int count = 0, depth = 0;
rt_uint32_t ptr; rt_uint32_t ptr;
udesc_t desc; udesc_t desc;
/* check parameter */ /* check parameter */
RT_ASSERT(intf_desc != RT_NULL); RT_ASSERT(intf_desc != RT_NULL);
RT_ASSERT(num < intf_desc->bNumEndpoints); RT_ASSERT(num < intf_desc->bNumEndpoints);
ptr = (rt_uint32_t)intf_desc + intf_desc->bLength; ptr = (rt_uint32_t)intf_desc + intf_desc->bLength;
while(count < intf_desc->bNumEndpoints) while(count < intf_desc->bNumEndpoints)
{ {
if(depth++ > 0x20) if(depth++ > 0x20)
{ {
*ep_desc = RT_NULL; *ep_desc = RT_NULL;
return -RT_EIO; return -RT_EIO;
} }
desc = (udesc_t)ptr; desc = (udesc_t)ptr;
if(desc->type == USB_DESC_TYPE_ENDPOINT) if(desc->type == USB_DESC_TYPE_ENDPOINT)
{ {
if(num == count) if(num == count)
{ {
*ep_desc = (uep_desc_t)desc; *ep_desc = (uep_desc_t)desc;
RT_DEBUG_LOG(RT_DEBUG_USB, RT_DEBUG_LOG(RT_DEBUG_USB,
("rt_usb_get_endpoint_descriptor: %d\n", num)); ("rt_usb_get_endpoint_descriptor: %d\n", num));
return RT_EOK; return RT_EOK;
} }
else count++; else count++;
} }
ptr = (rt_uint32_t)desc + desc->bLength; ptr = (rt_uint32_t)desc + desc->bLength;
} }
rt_kprintf("rt_usb_get_endpoint_descriptor %d failed\n", num); rt_kprintf("rt_usb_get_endpoint_descriptor %d failed\n", num);
return -RT_EIO; return -RT_EIO;
} }
...@@ -25,9 +25,9 @@ static rt_list_t _driver_list; ...@@ -25,9 +25,9 @@ static rt_list_t _driver_list;
*/ */
rt_err_t rt_usb_class_driver_init(void) rt_err_t rt_usb_class_driver_init(void)
{ {
rt_list_init(&_driver_list); rt_list_init(&_driver_list);
return RT_EOK; return RT_EOK;
} }
/** /**
...@@ -40,14 +40,14 @@ rt_err_t rt_usb_class_driver_init(void) ...@@ -40,14 +40,14 @@ rt_err_t rt_usb_class_driver_init(void)
rt_err_t rt_usb_class_driver_register(ucd_t drv) rt_err_t rt_usb_class_driver_register(ucd_t drv)
{ {
RT_ASSERT(drv != RT_NULL); RT_ASSERT(drv != RT_NULL);
if (drv == RT_NULL) return -RT_ERROR; if (drv == RT_NULL) return -RT_ERROR;
/* insert class driver into driver list */ /* insert class driver into driver list */
rt_list_insert_after(&_driver_list, &(drv->list)); rt_list_insert_after(&_driver_list, &(drv->list));
return RT_EOK; return RT_EOK;
} }
/** /**
...@@ -59,12 +59,12 @@ rt_err_t rt_usb_class_driver_register(ucd_t drv) ...@@ -59,12 +59,12 @@ rt_err_t rt_usb_class_driver_register(ucd_t drv)
*/ */
rt_err_t rt_usb_class_driver_unregister(ucd_t drv) rt_err_t rt_usb_class_driver_unregister(ucd_t drv)
{ {
RT_ASSERT(drv != RT_NULL); RT_ASSERT(drv != RT_NULL);
/* remove class driver from driver list */ /* remove class driver from driver list */
rt_list_remove(&(drv->list)); rt_list_remove(&(drv->list));
return RT_EOK; return RT_EOK;
} }
/** /**
...@@ -77,12 +77,12 @@ rt_err_t rt_usb_class_driver_unregister(ucd_t drv) ...@@ -77,12 +77,12 @@ rt_err_t rt_usb_class_driver_unregister(ucd_t drv)
*/ */
rt_err_t rt_usb_class_driver_run(ucd_t drv, void* args) rt_err_t rt_usb_class_driver_run(ucd_t drv, void* args)
{ {
RT_ASSERT(drv != RT_NULL); RT_ASSERT(drv != RT_NULL);
if(drv->run != RT_NULL) if(drv->run != RT_NULL)
drv->run(args); drv->run(args);
return RT_EOK; return RT_EOK;
} }
/** /**
...@@ -95,12 +95,12 @@ rt_err_t rt_usb_class_driver_run(ucd_t drv, void* args) ...@@ -95,12 +95,12 @@ rt_err_t rt_usb_class_driver_run(ucd_t drv, void* args)
*/ */
rt_err_t rt_usb_class_driver_stop(ucd_t drv, void* args) rt_err_t rt_usb_class_driver_stop(ucd_t drv, void* args)
{ {
RT_ASSERT(drv != RT_NULL); RT_ASSERT(drv != RT_NULL);
if(drv->stop != RT_NULL) if(drv->stop != RT_NULL)
drv->stop(args); drv->stop(args);
return RT_EOK; return RT_EOK;
} }
...@@ -114,32 +114,32 @@ rt_err_t rt_usb_class_driver_stop(ucd_t drv, void* args) ...@@ -114,32 +114,32 @@ rt_err_t rt_usb_class_driver_stop(ucd_t drv, void* args)
*/ */
ucd_t rt_usb_class_driver_find(int class_code, int subclass_code) ucd_t rt_usb_class_driver_find(int class_code, int subclass_code)
{ {
struct rt_list_node *node; struct rt_list_node *node;
/* enter critical */ /* enter critical */
if (rt_thread_self() != RT_NULL) if (rt_thread_self() != RT_NULL)
rt_enter_critical(); rt_enter_critical();
/* try to find driver object */ /* try to find driver object */
for (node = _driver_list.next; node != &_driver_list; node = node->next) for (node = _driver_list.next; node != &_driver_list; node = node->next)
{ {
ucd_t drv = ucd_t drv =
(ucd_t)rt_list_entry(node, struct uclass_driver, list); (ucd_t)rt_list_entry(node, struct uclass_driver, list);
if (drv->class_code == class_code) if (drv->class_code == class_code)
{ {
/* leave critical */ /* leave critical */
if (rt_thread_self() != RT_NULL) if (rt_thread_self() != RT_NULL)
rt_exit_critical(); rt_exit_critical();
return drv; return drv;
} }
} }
/* leave critical */ /* leave critical */
if (rt_thread_self() != RT_NULL) if (rt_thread_self() != RT_NULL)
rt_exit_critical(); rt_exit_critical();
/* not found */ /* not found */
return RT_NULL; return RT_NULL;
} }
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
#include <rtthread.h> #include <rtthread.h>
#include <drivers/usb_host.h> #include <drivers/usb_host.h>
#define USB_THREAD_STACK_SIZE 2048 #define USB_THREAD_STACK_SIZE 2048
static struct rt_messagequeue *usb_mq; static struct rt_messagequeue *usb_mq;
static struct uclass_driver hub_driver; static struct uclass_driver hub_driver;
...@@ -31,24 +31,24 @@ static struct uclass_driver hub_driver; ...@@ -31,24 +31,24 @@ static struct uclass_driver hub_driver;
* @return the error code, RT_EOK on successfully. * @return the error code, RT_EOK on successfully.
*/ */
rt_err_t rt_usb_hub_get_descriptor(uinst_t uinst, rt_uint8_t *buffer, rt_err_t rt_usb_hub_get_descriptor(uinst_t uinst, rt_uint8_t *buffer,
rt_size_t nbytes) rt_size_t nbytes)
{ {
struct ureqest setup; struct ureqest setup;
int timeout = 100; int timeout = 100;
/* parameter check */ /* parameter check */
RT_ASSERT(uinst != RT_NULL); RT_ASSERT(uinst != RT_NULL);
setup.request_type = USB_REQ_TYPE_DIR_IN | USB_REQ_TYPE_CLASS | setup.request_type = USB_REQ_TYPE_DIR_IN | USB_REQ_TYPE_CLASS |
USB_REQ_TYPE_DEVICE; USB_REQ_TYPE_DEVICE;
setup.request = USB_REQ_GET_DESCRIPTOR; setup.request = USB_REQ_GET_DESCRIPTOR;
setup.index = 0; setup.index = 0;
setup.length = nbytes; setup.length = nbytes;
setup.value = USB_DESC_TYPE_HUB << 8; setup.value = USB_DESC_TYPE_HUB << 8;
if(rt_usb_hcd_control_xfer(uinst->hcd, uinst, &setup, buffer, nbytes, if(rt_usb_hcd_control_xfer(uinst->hcd, uinst, &setup, buffer, nbytes,
timeout) == nbytes) return RT_EOK; timeout) == nbytes) return RT_EOK;
else return -RT_FALSE; else return -RT_FALSE;
} }
/** /**
...@@ -62,23 +62,23 @@ rt_err_t rt_usb_hub_get_descriptor(uinst_t uinst, rt_uint8_t *buffer, ...@@ -62,23 +62,23 @@ rt_err_t rt_usb_hub_get_descriptor(uinst_t uinst, rt_uint8_t *buffer,
*/ */
rt_err_t rt_usb_hub_get_status(uinst_t uinst, rt_uint8_t* buffer) rt_err_t rt_usb_hub_get_status(uinst_t uinst, rt_uint8_t* buffer)
{ {
struct ureqest setup; struct ureqest setup;
int timeout = 100; int timeout = 100;
int length = 4; int length = 4;
/* parameter check */ /* parameter check */
RT_ASSERT(uinst != RT_NULL); RT_ASSERT(uinst != RT_NULL);
setup.request_type = USB_REQ_TYPE_DIR_IN | USB_REQ_TYPE_CLASS | setup.request_type = USB_REQ_TYPE_DIR_IN | USB_REQ_TYPE_CLASS |
USB_REQ_TYPE_DEVICE; USB_REQ_TYPE_DEVICE;
setup.request = USB_REQ_GET_STATUS; setup.request = USB_REQ_GET_STATUS;
setup.index = 0; setup.index = 0;
setup.length = length; setup.length = length;
setup.value = 0; setup.value = 0;
if(rt_usb_hcd_control_xfer(uinst->hcd, uinst, &setup, buffer, length, if(rt_usb_hcd_control_xfer(uinst->hcd, uinst, &setup, buffer, length,
timeout) == length) return RT_EOK; timeout) == length) return RT_EOK;
else return -RT_FALSE; else return -RT_FALSE;
} }
/** /**
...@@ -92,33 +92,33 @@ rt_err_t rt_usb_hub_get_status(uinst_t uinst, rt_uint8_t* buffer) ...@@ -92,33 +92,33 @@ rt_err_t rt_usb_hub_get_status(uinst_t uinst, rt_uint8_t* buffer)
* @return the error code, RT_EOK on successfully. * @return the error code, RT_EOK on successfully.
*/ */
rt_err_t rt_usb_hub_get_port_status(uhubinst_t uhub, rt_uint16_t port, rt_err_t rt_usb_hub_get_port_status(uhubinst_t uhub, rt_uint16_t port,
rt_uint8_t* buffer) rt_uint8_t* buffer)
{ {
struct ureqest setup; struct ureqest setup;
int timeout = 100; int timeout = 100;
int length = 4; int length = 4;
/* parameter check */ /* parameter check */
RT_ASSERT(uhub != RT_NULL); RT_ASSERT(uhub != RT_NULL);
/* get roothub port status */ /* get roothub port status */
if(uhub->is_roothub) if(uhub->is_roothub)
{ {
rt_usb_hcd_hub_control(uhub->hcd, port, RH_GET_PORT_STATUS, rt_usb_hcd_hub_control(uhub->hcd, port, RH_GET_PORT_STATUS,
(void*)buffer); (void*)buffer);
return RT_EOK; return RT_EOK;
} }
setup.request_type = USB_REQ_TYPE_DIR_IN | USB_REQ_TYPE_CLASS | setup.request_type = USB_REQ_TYPE_DIR_IN | USB_REQ_TYPE_CLASS |
USB_REQ_TYPE_OTHER; USB_REQ_TYPE_OTHER;
setup.request = USB_REQ_GET_STATUS; setup.request = USB_REQ_GET_STATUS;
setup.index = port; setup.index = port;
setup.length = 4; setup.length = 4;
setup.value = 0; setup.value = 0;
if(rt_usb_hcd_control_xfer(uhub->hcd, uhub->self, &setup, buffer, if(rt_usb_hcd_control_xfer(uhub->hcd, uhub->self, &setup, buffer,
length, timeout) == timeout) return RT_EOK; length, timeout) == timeout) return RT_EOK;
else return -RT_FALSE; else return -RT_FALSE;
} }
/** /**
...@@ -132,32 +132,32 @@ rt_err_t rt_usb_hub_get_port_status(uhubinst_t uhub, rt_uint16_t port, ...@@ -132,32 +132,32 @@ rt_err_t rt_usb_hub_get_port_status(uhubinst_t uhub, rt_uint16_t port,
* @return the error code, RT_EOK on successfully. * @return the error code, RT_EOK on successfully.
*/ */
rt_err_t rt_usb_hub_clear_port_feature(uhubinst_t uhub, rt_uint16_t port, rt_err_t rt_usb_hub_clear_port_feature(uhubinst_t uhub, rt_uint16_t port,
rt_uint16_t feature) rt_uint16_t feature)
{ {
struct ureqest setup; struct ureqest setup;
int timeout = 100; int timeout = 100;
/* parameter check */ /* parameter check */
RT_ASSERT(uhub != RT_NULL); RT_ASSERT(uhub != RT_NULL);
/* clear roothub feature */ /* clear roothub feature */
if(uhub->is_roothub) if(uhub->is_roothub)
{ {
rt_usb_hcd_hub_control(uhub->hcd, port, RH_CLEAR_PORT_FEATURE, rt_usb_hcd_hub_control(uhub->hcd, port, RH_CLEAR_PORT_FEATURE,
(void*)feature); (void*)feature);
return RT_EOK; return RT_EOK;
} }
setup.request_type = USB_REQ_TYPE_DIR_OUT | USB_REQ_TYPE_CLASS | setup.request_type = USB_REQ_TYPE_DIR_OUT | USB_REQ_TYPE_CLASS |
USB_REQ_TYPE_OTHER; USB_REQ_TYPE_OTHER;
setup.request = USB_REQ_CLEAR_FEATURE; setup.request = USB_REQ_CLEAR_FEATURE;
setup.index = port; setup.index = port;
setup.length = 0; setup.length = 0;
setup.value = feature; setup.value = feature;
if(rt_usb_hcd_control_xfer(uhub->hcd, uhub->self, &setup, RT_NULL, 0, if(rt_usb_hcd_control_xfer(uhub->hcd, uhub->self, &setup, RT_NULL, 0,
timeout) == 0) return RT_EOK; timeout) == 0) return RT_EOK;
else return -RT_FALSE; else return -RT_FALSE;
} }
/** /**
...@@ -171,32 +171,32 @@ rt_err_t rt_usb_hub_clear_port_feature(uhubinst_t uhub, rt_uint16_t port, ...@@ -171,32 +171,32 @@ rt_err_t rt_usb_hub_clear_port_feature(uhubinst_t uhub, rt_uint16_t port,
* @return the error code, RT_EOK on successfully. * @return the error code, RT_EOK on successfully.
*/ */
rt_err_t rt_usb_hub_set_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_uint16_t feature)
{ {
struct ureqest setup; struct ureqest setup;
int timeout = 100; int timeout = 100;
/* parameter check */ /* parameter check */
RT_ASSERT(uhub != RT_NULL); RT_ASSERT(uhub != RT_NULL);
/* clear roothub feature */ /* clear roothub feature */
if(uhub->is_roothub) if(uhub->is_roothub)
{ {
rt_usb_hcd_hub_control(uhub->hcd, port, RH_SET_PORT_FEATURE, rt_usb_hcd_hub_control(uhub->hcd, port, RH_SET_PORT_FEATURE,
(void*)feature); (void*)feature);
return RT_EOK; return RT_EOK;
} }
setup.request_type = USB_REQ_TYPE_DIR_OUT | USB_REQ_TYPE_CLASS | setup.request_type = USB_REQ_TYPE_DIR_OUT | USB_REQ_TYPE_CLASS |
USB_REQ_TYPE_OTHER; USB_REQ_TYPE_OTHER;
setup.request = USB_REQ_SET_FEATURE; setup.request = USB_REQ_SET_FEATURE;
setup.index = port; setup.index = port;
setup.length = 0; setup.length = 0;
setup.value = feature; setup.value = feature;
if(rt_usb_hcd_control_xfer(uhub->hcd, uhub->self, &setup, RT_NULL, 0, if(rt_usb_hcd_control_xfer(uhub->hcd, uhub->self, &setup, RT_NULL, 0,
timeout) == 0) return RT_EOK; timeout) == 0) return RT_EOK;
else return -RT_FALSE; else return -RT_FALSE;
} }
/** /**
...@@ -209,31 +209,31 @@ rt_err_t rt_usb_hub_set_port_feature(uhubinst_t uhub, rt_uint16_t port, ...@@ -209,31 +209,31 @@ rt_err_t rt_usb_hub_set_port_feature(uhubinst_t uhub, rt_uint16_t port,
*/ */
rt_err_t rt_usb_hub_reset_port(uhubinst_t uhub, rt_uint16_t port) rt_err_t rt_usb_hub_reset_port(uhubinst_t uhub, rt_uint16_t port)
{ {
rt_err_t ret; rt_err_t ret;
rt_uint32_t pstatus; rt_uint32_t pstatus;
/* parameter check */ /* parameter check */
RT_ASSERT(uhub != RT_NULL); RT_ASSERT(uhub != RT_NULL);
rt_thread_delay(50); rt_thread_delay(50);
/* reset hub port */ /* reset hub port */
ret = rt_usb_hub_set_port_feature(uhub, port, PORT_FEAT_RESET); ret = rt_usb_hub_set_port_feature(uhub, port, PORT_FEAT_RESET);
if(ret != RT_EOK) return ret; if(ret != RT_EOK) return ret;
while(1) while(1)
{ {
ret = rt_usb_hub_get_port_status(uhub, port, (rt_uint8_t*)&pstatus); ret = rt_usb_hub_get_port_status(uhub, port, (rt_uint8_t*)&pstatus);
if(!(pstatus & PORT_PRS)) break; if(!(pstatus & PORT_PRS)) break;
} }
/* clear port reset feature */ /* clear port reset feature */
ret = rt_usb_hub_clear_port_feature(uhub, port, PORT_FEAT_C_RESET); ret = rt_usb_hub_clear_port_feature(uhub, port, PORT_FEAT_C_RESET);
if(ret != RT_EOK) return ret; if(ret != RT_EOK) return ret;
rt_thread_delay(50); rt_thread_delay(50);
return RT_EOK; return RT_EOK;
} }
/** /**
...@@ -246,30 +246,30 @@ rt_err_t rt_usb_hub_reset_port(uhubinst_t uhub, rt_uint16_t port) ...@@ -246,30 +246,30 @@ rt_err_t rt_usb_hub_reset_port(uhubinst_t uhub, rt_uint16_t port)
*/ */
rt_err_t rt_usb_hub_port_debounce(uhubinst_t uhub, rt_uint16_t port) rt_err_t rt_usb_hub_port_debounce(uhubinst_t uhub, rt_uint16_t port)
{ {
rt_err_t ret; rt_err_t ret;
int i = 0, times = 20; int i = 0, times = 20;
rt_uint32_t pstatus; rt_uint32_t pstatus;
rt_bool_t connect = RT_TRUE; rt_bool_t connect = RT_TRUE;
/* parameter check */ /* parameter check */
RT_ASSERT(uhub != RT_NULL); RT_ASSERT(uhub != RT_NULL);
for(i=0; i<times; i++) for(i=0; i<times; i++)
{ {
ret = rt_usb_hub_get_port_status(uhub, port, (rt_uint8_t*)&pstatus); ret = rt_usb_hub_get_port_status(uhub, port, (rt_uint8_t*)&pstatus);
if(ret != RT_EOK) return ret; if(ret != RT_EOK) return ret;
if(!(pstatus & PORT_CCS)) if(!(pstatus & PORT_CCS))
{ {
connect = RT_FALSE; connect = RT_FALSE;
break; break;
} }
rt_thread_delay(1); rt_thread_delay(1);
} }
if(connect) return RT_EOK; if(connect) return RT_EOK;
else return -RT_ERROR; else return -RT_ERROR;
} }
/** /**
...@@ -282,68 +282,68 @@ rt_err_t rt_usb_hub_port_debounce(uhubinst_t uhub, rt_uint16_t port) ...@@ -282,68 +282,68 @@ rt_err_t rt_usb_hub_port_debounce(uhubinst_t uhub, rt_uint16_t port)
*/ */
static rt_err_t rt_usb_hub_port_change(uhubinst_t uhub) static rt_err_t rt_usb_hub_port_change(uhubinst_t uhub)
{ {
int i; int i;
rt_bool_t reconnect; rt_bool_t reconnect;
/* parameter check */ /* parameter check */
RT_ASSERT(uhub != RT_NULL); RT_ASSERT(uhub != RT_NULL);
/* get usb device instance */ /* get usb device instance */
for (i = 0; i < uhub->num_ports; i++) for (i = 0; i < uhub->num_ports; i++)
{ {
rt_err_t ret; rt_err_t ret;
uinst_t uinst; uinst_t uinst;
rt_uint32_t pstatus = 0; rt_uint32_t pstatus = 0;
reconnect = RT_FALSE; reconnect = RT_FALSE;
/* get hub port status */ /* get hub port status */
ret = rt_usb_hub_get_port_status(uhub, i + 1, (rt_uint8_t*)&pstatus); ret = rt_usb_hub_get_port_status(uhub, i + 1, (rt_uint8_t*)&pstatus);
if(ret != RT_EOK) continue; if(ret != RT_EOK) continue;
RT_DEBUG_LOG(RT_DEBUG_USB, ("port_status 0x%x\n", pstatus)); RT_DEBUG_LOG(RT_DEBUG_USB, ("port_status 0x%x\n", pstatus));
/* check port status change */ /* check port status change */
if ((pstatus & PORT_CCSC)) if ((pstatus & PORT_CCSC))
{ {
/* clear port status change feature */ /* clear port status change feature */
rt_usb_hub_clear_port_feature(uhub, i + 1, PORT_FEAT_C_CONNECTION); rt_usb_hub_clear_port_feature(uhub, i + 1, PORT_FEAT_C_CONNECTION);
reconnect = RT_TRUE; reconnect = RT_TRUE;
} }
if(pstatus & PORT_PESC) if(pstatus & PORT_PESC)
{ {
rt_usb_hub_clear_port_feature(uhub, i + 1, PORT_FEAT_C_ENABLE); rt_usb_hub_clear_port_feature(uhub, i + 1, PORT_FEAT_C_ENABLE);
reconnect = RT_TRUE; reconnect = RT_TRUE;
} }
if(reconnect) if(reconnect)
{ {
if(uhub->child[i]) if(uhub->child[i]->status != UINST_STATUS_IDLE)
rt_usb_detach_instance(uhub->child[i]); rt_usb_detach_instance(uhub->child[i]);
ret = rt_usb_hub_port_debounce(uhub, i + 1); ret = rt_usb_hub_port_debounce(uhub, i + 1);
if(ret != RT_EOK) continue; if(ret != RT_EOK) continue;
/* allocate an usb instance for new connected device */ /* allocate an usb instance for new connected device */
uinst = rt_usb_alloc_instance(); uinst = rt_usb_alloc_instance();
if(uinst == RT_NULL) break; if(uinst == RT_NULL) break;
/* set usb device speed */ /* set usb device speed */
uinst->speed = (pstatus & PORT_LSDA) ? 1 : 0; uinst->speed = (pstatus & PORT_LSDA) ? 1 : 0;
uinst->parent = uhub; uinst->parent = uhub;
uinst->hcd = uhub->hcd; uinst->hcd = uhub->hcd;
uhub->child[i] = uinst; uhub->child[i] = uinst;
/* reset usb roothub port */ /* reset usb roothub port */
rt_usb_hub_reset_port(uhub, i + 1); rt_usb_hub_reset_port(uhub, i + 1);
/* attatch the usb instance to the hcd */ /* attatch the usb instance to the hcd */
rt_usb_attatch_instance(uinst); rt_usb_attatch_instance(uinst);
} }
} }
return RT_EOK; return RT_EOK;
} }
/** /**
...@@ -355,32 +355,32 @@ static rt_err_t rt_usb_hub_port_change(uhubinst_t uhub) ...@@ -355,32 +355,32 @@ static rt_err_t rt_usb_hub_port_change(uhubinst_t uhub)
*/ */
static void rt_usb_hub_irq(void* context) static void rt_usb_hub_irq(void* context)
{ {
upipe_t pipe; upipe_t pipe;
uifinst_t ifinst; uifinst_t ifinst;
uhubinst_t uhub; uhubinst_t uhub;
int timeout = 100; int timeout = 100;
RT_ASSERT(context != RT_NULL); RT_ASSERT(context != RT_NULL);
pipe = (upipe_t)context; pipe = (upipe_t)context;
ifinst = pipe->ifinst; ifinst = pipe->ifinst;
uhub = (uhubinst_t)ifinst->user_data; uhub = (uhubinst_t)ifinst->user_data;
if(pipe->status != UPIPE_STATUS_OK) if(pipe->status != UPIPE_STATUS_OK)
{ {
rt_kprintf("hub irq error\n"); rt_kprintf("hub irq error\n");
return; return;
} }
rt_usb_hub_port_change(uhub); rt_usb_hub_port_change(uhub);
rt_kprintf("hub int xfer...\n"); rt_kprintf("hub int xfer...\n");
/* parameter check */ /* parameter check */
RT_ASSERT(pipe->ifinst->uinst->hcd != RT_NULL); RT_ASSERT(pipe->ifinst->uinst->hcd != RT_NULL);
rt_usb_hcd_int_xfer(ifinst->uinst->hcd, pipe, uhub->buffer, rt_usb_hcd_int_xfer(ifinst->uinst->hcd, pipe, uhub->buffer,
pipe->ep.wMaxPacketSize, timeout); pipe->ep.wMaxPacketSize, timeout);
} }
/** /**
...@@ -393,90 +393,90 @@ static void rt_usb_hub_irq(void* context) ...@@ -393,90 +393,90 @@ static void rt_usb_hub_irq(void* context)
*/ */
static rt_err_t rt_usb_hub_run(void *arg) static rt_err_t rt_usb_hub_run(void *arg)
{ {
int i = 0; int i = 0;
rt_err_t ret = RT_EOK; rt_err_t ret = RT_EOK;
uep_desc_t ep_desc; uep_desc_t ep_desc;
uhubinst_t uhub; uhubinst_t uhub;
uinst_t uinst; uinst_t uinst;
uifinst_t ifinst = (uifinst_t)arg; uifinst_t ifinst = (uifinst_t)arg;
int timeout = 300; int timeout = 300;
/* paremeter check */ /* paremeter check */
RT_ASSERT(ifinst != RT_NULL); RT_ASSERT(ifinst != RT_NULL);
RT_DEBUG_LOG(RT_DEBUG_USB, ("rt_usb_hub_run\n")); RT_DEBUG_LOG(RT_DEBUG_USB, ("rt_usb_hub_run\n"));
/* get usb device instance */ /* get usb device instance */
uinst = ifinst->uinst; uinst = ifinst->uinst;
/* create a hub instance */ /* create a hub instance */
uhub = rt_malloc(sizeof(struct uhubinst)); uhub = rt_malloc(sizeof(struct uhubinst));
rt_memset(uhub, 0, sizeof(struct uhubinst)); rt_memset(uhub, 0, sizeof(struct uhubinst));
/* make interface instance's user data point to hub instance */ /* make interface instance's user data point to hub instance */
ifinst->user_data = (void*)uhub; ifinst->user_data = (void*)uhub;
/* get hub descriptor head */ /* get hub descriptor head */
ret = rt_usb_hub_get_descriptor(uinst, (rt_uint8_t*)&uhub->hub_desc, 8); ret = rt_usb_hub_get_descriptor(uinst, (rt_uint8_t*)&uhub->hub_desc, 8);
if(ret != RT_EOK) if(ret != RT_EOK)
{ {
rt_kprintf("get hub descriptor failed\n"); rt_kprintf("get hub descriptor failed\n");
return -RT_ERROR; return -RT_ERROR;
} }
/* get full hub descriptor */ /* get full hub descriptor */
ret = rt_usb_hub_get_descriptor(uinst, (rt_uint8_t*)&uhub->hub_desc, ret = rt_usb_hub_get_descriptor(uinst, (rt_uint8_t*)&uhub->hub_desc,
uhub->hub_desc.length); uhub->hub_desc.length);
if(ret != RT_EOK) if(ret != RT_EOK)
{ {
rt_kprintf("get hub descriptor again failed\n"); rt_kprintf("get hub descriptor again failed\n");
return -RT_ERROR; return -RT_ERROR;
} }
/* get hub ports number */ /* get hub ports number */
uhub->num_ports = uhub->hub_desc.num_ports; uhub->num_ports = uhub->hub_desc.num_ports;
uhub->hcd = uinst->hcd; uhub->hcd = uinst->hcd;
uhub->self = uinst; uhub->self = uinst;
/* reset all hub ports */ /* reset all hub ports */
for (i = 0; i < uhub->num_ports; i++) for (i = 0; i < uhub->num_ports; i++)
{ {
rt_usb_hub_set_port_feature(uhub, i + 1, PORT_FEAT_POWER); rt_usb_hub_set_port_feature(uhub, i + 1, PORT_FEAT_POWER);
rt_thread_delay(uhub->hub_desc.pwron_to_good rt_thread_delay(uhub->hub_desc.pwron_to_good
* 2 * RT_TICK_PER_SECOND / 1000 ); * 2 * RT_TICK_PER_SECOND / 1000 );
} }
if(ifinst->intf_desc->bNumEndpoints != 1) if(ifinst->intf_desc->bNumEndpoints != 1)
return -RT_ERROR; return -RT_ERROR;
/* get endpoint descriptor from interface descriptor */ /* get endpoint descriptor from interface descriptor */
rt_usb_get_endpoint_descriptor(ifinst->intf_desc, 0, &ep_desc); rt_usb_get_endpoint_descriptor(ifinst->intf_desc, 0, &ep_desc);
if(ep_desc == RT_NULL) if(ep_desc == RT_NULL)
{ {
rt_kprintf("rt_usb_get_endpoint_descriptor error\n"); rt_kprintf("rt_usb_get_endpoint_descriptor error\n");
return -RT_ERROR; return -RT_ERROR;
} }
/* the endpoint type of hub class should be interrupt */ /* the endpoint type of hub class should be interrupt */
if( USB_EP_ATTR(ep_desc->bmAttributes) == USB_EP_ATTR_INT) if( USB_EP_ATTR(ep_desc->bmAttributes) == USB_EP_ATTR_INT)
{ {
/* the endpoint direction of hub class should be in */ /* the endpoint direction of hub class should be in */
if(ep_desc->bEndpointAddress & USB_DIR_IN) if(ep_desc->bEndpointAddress & USB_DIR_IN)
{ {
/* allocate a pipe according to the endpoint type */ /* allocate a pipe according to the endpoint type */
rt_usb_hcd_alloc_pipe(uinst->hcd, &uhub->pipe_in, ifinst, rt_usb_hcd_alloc_pipe(uinst->hcd, &uhub->pipe_in, ifinst,
ep_desc, rt_usb_hub_irq); ep_desc, rt_usb_hub_irq);
} }
else return -RT_ERROR; else return -RT_ERROR;
} }
/* parameter check */ /* parameter check */
RT_ASSERT(uinst->hcd != RT_NULL); RT_ASSERT(uinst->hcd != RT_NULL);
rt_usb_hcd_int_xfer(uinst->hcd, uhub->pipe_in, uhub->buffer, rt_usb_hcd_int_xfer(uinst->hcd, uhub->pipe_in, uhub->buffer,
uhub->pipe_in->ep.wMaxPacketSize, timeout); uhub->pipe_in->ep.wMaxPacketSize, timeout);
return RT_EOK; return RT_EOK;
} }
/** /**
...@@ -489,32 +489,32 @@ static rt_err_t rt_usb_hub_run(void *arg) ...@@ -489,32 +489,32 @@ static rt_err_t rt_usb_hub_run(void *arg)
*/ */
static rt_err_t rt_usb_hub_stop(void* arg) static rt_err_t rt_usb_hub_stop(void* arg)
{ {
int i; int i;
uhubinst_t uhub; uhubinst_t uhub;
uinst_t uinst; uinst_t uinst;
uifinst_t ifinst = (uifinst_t)arg; uifinst_t ifinst = (uifinst_t)arg;
/* paremeter check */ /* paremeter check */
RT_ASSERT(ifinst != RT_NULL); RT_ASSERT(ifinst != RT_NULL);
RT_DEBUG_LOG(RT_DEBUG_USB, ("rt_usb_hub_stop\n")); RT_DEBUG_LOG(RT_DEBUG_USB, ("rt_usb_hub_stop\n"));
uinst = ifinst->uinst; uinst = ifinst->uinst;
uhub = (uhubinst_t)ifinst->user_data; uhub = (uhubinst_t)ifinst->user_data;
if(uhub->pipe_in != RT_NULL) if(uhub->pipe_in != RT_NULL)
rt_usb_hcd_free_pipe(uinst->hcd, uhub->pipe_in); rt_usb_hcd_free_pipe(uinst->hcd, uhub->pipe_in);
for(i=0; i<uhub->num_ports; i++) for(i=0; i<uhub->num_ports; i++)
{ {
if(uhub->child[i] != RT_NULL) if(uhub->child[i] != RT_NULL)
rt_usb_detach_instance(uhub->child[i]); rt_usb_detach_instance(uhub->child[i]);
} }
if(uhub != RT_NULL) rt_free(uhub); if(uhub != RT_NULL) rt_free(uhub);
if(ifinst != RT_NULL) rt_free(ifinst); if(ifinst != RT_NULL) rt_free(ifinst);
return RT_EOK; return RT_EOK;
} }
/** /**
...@@ -524,13 +524,13 @@ static rt_err_t rt_usb_hub_stop(void* arg) ...@@ -524,13 +524,13 @@ static rt_err_t rt_usb_hub_stop(void* arg)
* @return the error code, RT_EOK on successfully. * @return the error code, RT_EOK on successfully.
*/ */
ucd_t rt_usb_class_driver_hub(void) ucd_t rt_usb_class_driver_hub(void)
{ {
hub_driver.class_code = USB_CLASS_HUB; hub_driver.class_code = USB_CLASS_HUB;
hub_driver.run = rt_usb_hub_run; hub_driver.run = rt_usb_hub_run;
hub_driver.stop = rt_usb_hub_stop; hub_driver.stop = rt_usb_hub_stop;
return &hub_driver; return &hub_driver;
} }
/** /**
...@@ -542,30 +542,30 @@ ucd_t rt_usb_class_driver_hub(void) ...@@ -542,30 +542,30 @@ ucd_t rt_usb_class_driver_hub(void)
* @return none. * @return none.
*/ */
static void rt_usb_hub_thread_entry(void* parameter) static void rt_usb_hub_thread_entry(void* parameter)
{ {
while(1) while(1)
{ {
struct umsg msg; struct umsg msg;
/* receive message */ /* receive message */
if(rt_mq_recv(usb_mq, &msg, sizeof(struct umsg), RT_WAITING_FOREVER) if(rt_mq_recv(usb_mq, &msg, sizeof(struct umsg), RT_WAITING_FOREVER)
!= RT_EOK ) continue; != RT_EOK ) continue;
RT_DEBUG_LOG(RT_DEBUG_USB, ("msg type %d\n", msg.type)); RT_DEBUG_LOG(RT_DEBUG_USB, ("msg type %d\n", msg.type));
switch (msg.type) switch (msg.type)
{ {
case USB_MSG_CONNECT_CHANGE: case USB_MSG_CONNECT_CHANGE:
rt_usb_hub_port_change(msg.content.uhub); rt_usb_hub_port_change(msg.content.uhub);
break; break;
case USB_MSG_CALLBACK: case USB_MSG_CALLBACK:
/* invoke callback */ /* invoke callback */
msg.content.cb.function(msg.content.cb.context); msg.content.cb.function(msg.content.cb.context);
break; break;
default: default:
break; break;
} }
} }
} }
/** /**
...@@ -578,12 +578,12 @@ static void rt_usb_hub_thread_entry(void* parameter) ...@@ -578,12 +578,12 @@ static void rt_usb_hub_thread_entry(void* parameter)
*/ */
rt_err_t rt_usb_post_event(struct umsg* msg, rt_size_t size) rt_err_t rt_usb_post_event(struct umsg* msg, rt_size_t size)
{ {
RT_ASSERT(msg != RT_NULL); RT_ASSERT(msg != RT_NULL);
/* send message to usb message queue */ /* send message to usb message queue */
rt_mq_send(usb_mq, (void*)msg, size); rt_mq_send(usb_mq, (void*)msg, size);
return RT_EOK; return RT_EOK;
} }
/** /**
...@@ -594,18 +594,18 @@ rt_err_t rt_usb_post_event(struct umsg* msg, rt_size_t size) ...@@ -594,18 +594,18 @@ rt_err_t rt_usb_post_event(struct umsg* msg, rt_size_t size)
*/ */
void rt_usb_hub_thread(void) void rt_usb_hub_thread(void)
{ {
rt_thread_t thread; rt_thread_t thread;
/* create usb message queue */ /* create usb message queue */
usb_mq = rt_mq_create("usbh", 32, 16, RT_IPC_FLAG_FIFO); usb_mq = rt_mq_create("usbh", 32, 16, RT_IPC_FLAG_FIFO);
/* create usb hub thread */ /* create usb hub thread */
thread = rt_thread_create("usbh", rt_usb_hub_thread_entry, RT_NULL, thread = rt_thread_create("usbh", rt_usb_hub_thread_entry, RT_NULL,
USB_THREAD_STACK_SIZE, 8, 20); USB_THREAD_STACK_SIZE, 8, 20);
if(thread != RT_NULL) if(thread != RT_NULL)
{ {
/* startup usb host thread */ /* startup usb host thread */
rt_thread_startup(thread); rt_thread_startup(thread);
} }
} }
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册