add ADK protocol implement & format code style

git-svn-id: https://rt-thread.googlecode.com/svn/trunk@2219 bbd45198-f89e-11dd-88c7-29a3b14d5316
This commit is contained in:
qiuyiuestc@gmail.com 2012-07-16 02:20:20 +00:00
parent 70cee4b82e
commit 1016e3ae5b
8 changed files with 1315 additions and 1113 deletions

View File

@ -17,183 +17,183 @@
#include <rtthread.h>
#define RT_DEBUG_USB 0x01
#define RT_DEBUG_USB 0x01
#define USB_MAX_DEVICE 0x20
#define USB_MAX_INTERFACE 0x08
#define USB_HUB_PORT_NUM 0x04
#define SIZEOF_USB_REQUEST 0x08
#define USB_MAX_DEVICE 0x20
#define USB_MAX_INTERFACE 0x08
#define USB_HUB_PORT_NUM 0x04
#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 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_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_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_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_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_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_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_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_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_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_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 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
#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
#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'.
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
#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_STATUS_LOCAL_POWER 0x0001
#define HUB_STATUS_OVERCURRENT 0x0002
#define HUB_CHANGE_LOCAL_POWER 0x0001
#define HUB_CHANGE_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 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))
((((x) & 0xff000000) >> 24) | \
(((x) & 0x00ff0000) >> 8) | \
(((x) & 0x0000ff00) << 8) | \
(((x) & 0x000000ff) << 24))
typedef void (*func_callback)(void *context);
@ -203,216 +203,216 @@ struct uhubinst;
enum umsg_type
{
USB_MSG_CONNECT_CHANGE,
USB_MSG_CALLBACK,
USB_MSG_CONNECT_CHANGE,
USB_MSG_CALLBACK,
};
typedef enum umsg_type umsg_type;
struct usb_descriptor
{
rt_uint8_t bLength;
rt_uint8_t type;
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;
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 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;
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;
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;
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];
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;
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;
int class_code;
int subclass_code;
rt_err_t (*run)(void* arg);
rt_err_t (*stop)(void* arg);
rt_list_t list;
int class_code;
int subclass_code;
rt_err_t (*run)(void* arg);
rt_err_t (*stop)(void* arg);
void* user_data;
void* user_data;
};
typedef struct uclass_driver* ucd_t;
struct uprotocal
{
rt_list_t list;
int pro_id;
rt_err_t (*init)(void* arg);
rt_err_t (*callback)(void* arg);
rt_list_t list;
int pro_id;
rt_err_t (*init)(void* arg);
rt_err_t (*callback)(void* arg);
};
typedef struct uprotocal* uprotocal_t;
struct uinstance
{
struct udevice_descriptor dev_desc;
ucfg_desc_t cfg_desc;
struct uhcd *hcd;
struct udevice_descriptor dev_desc;
ucfg_desc_t cfg_desc;
struct uhcd *hcd;
rt_uint8_t status;
rt_uint8_t type;
rt_uint8_t index;
rt_uint8_t address;
rt_uint8_t speed;
rt_uint8_t max_packet_size;
rt_uint8_t port;
rt_uint8_t status;
rt_uint8_t type;
rt_uint8_t index;
rt_uint8_t address;
rt_uint8_t speed;
rt_uint8_t max_packet_size;
rt_uint8_t port;
struct uhubinst* parent;
struct uifinst* ifinst[USB_MAX_INTERFACE];
struct uhubinst* parent;
struct uifinst* ifinst[USB_MAX_INTERFACE];
};
typedef struct uinstance* uinst_t;
struct uifinst
{
uinst_t uinst;
uintf_desc_t intf_desc;
uinst_t uinst;
uintf_desc_t intf_desc;
ucd_t drv;
void *user_data;
ucd_t drv;
void *user_data;
};
typedef struct uifinst* uifinst_t;
struct upipe
{
rt_uint32_t status;
struct uendpoint_descriptor ep;
uifinst_t ifinst;
func_callback callback;
void* user_data;
rt_uint32_t status;
struct uendpoint_descriptor ep;
uifinst_t ifinst;
func_callback callback;
void* user_data;
};
typedef struct upipe* upipe_t;
struct umsg
{
umsg_type type;
union
{
struct uhubinst* uhub;
struct
{
func_callback function;
void *context;
}cb;
}content;
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;
rt_uint8_t num_ports;
rt_uint32_t port_status[USB_HUB_PORT_NUM];
struct uinstance* child[USB_HUB_PORT_NUM];
struct uhub_descriptor hub_desc;
rt_uint8_t num_ports;
rt_uint32_t port_status[USB_HUB_PORT_NUM];
struct uinstance* child[USB_HUB_PORT_NUM];
rt_bool_t is_roothub;
upipe_t pipe_in;
rt_uint8_t buffer[8];
struct uinstance* self;
struct uhcd *hcd;
};
rt_bool_t is_roothub;
upipe_t pipe_in;
rt_uint8_t buffer[8];
struct uinstance* self;
struct uhcd *hcd;
};
typedef struct uhubinst* uhubinst_t;
struct uhcd_ops
{
int (*ctl_xfer)(uinst_t inst, ureq_t setup, 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 (*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,
func_callback callback);
rt_err_t (*free_pipe)(upipe_t pipe);
rt_err_t (*hub_ctrl)(rt_uint16_t port, rt_uint8_t cmd, void *args);
int (*ctl_xfer)(uinst_t inst, ureq_t setup, 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 (*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,
func_callback callback);
rt_err_t (*free_pipe)(upipe_t pipe);
rt_err_t (*hub_ctrl)(rt_uint16_t port, rt_uint8_t cmd, void *args);
};
struct uhcd
{
struct rt_device parent;
struct uhcd_ops* ops;
struct rt_device parent;
struct uhcd_ops* ops;
};
typedef struct uhcd* uhcd_t;
@ -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_detach_instance(uinst_t uinst);
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_address(uinst_t uinst);
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_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,
uep_desc_t* ep_desc);
uep_desc_t* ep_desc);
/* usb class driver interface */
rt_err_t rt_usb_class_driver_init(void);
@ -455,97 +455,97 @@ uprotocal_t rt_usb_hid_protocal_mouse(void);
/* usb hub interface */
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_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_uint16_t feature);
rt_uint16_t feature);
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_post_event(struct umsg* 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,
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 */
RT_ASSERT(hcd != RT_NULL);
RT_ASSERT(hcd->ops != RT_NULL);
RT_ASSERT(hcd->ops->alloc_pipe!= RT_NULL);
/* 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);
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_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);
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);
return hcd->ops->free_pipe(pipe);
}
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->ifinst == RT_NULL) return -1;
if(pipe->ifinst->uinst == RT_NULL) return -1;
if(pipe->ifinst->uinst->status == UINST_STATUS_IDLE)
return -1;
if(pipe == RT_NULL) return -1;
if(pipe->ifinst == RT_NULL) return -1;
if(pipe->ifinst->uinst == RT_NULL) return -1;
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);
/* 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);
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,
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 */
RT_ASSERT(hcd != RT_NULL);
RT_ASSERT(hcd->ops != RT_NULL);
RT_ASSERT(hcd->ops->ctl_xfer!= RT_NULL);
/* 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);
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,
int nbytes, int timeout)
{
if(pipe == RT_NULL) return -1;
if(pipe->ifinst == RT_NULL) return -1;
if(pipe->ifinst->uinst == RT_NULL) return -1;
if(pipe->ifinst->uinst->status == UINST_STATUS_IDLE)
return -1;
int nbytes, int timeout)
{
if(pipe == RT_NULL) return -1;
if(pipe->ifinst == RT_NULL) return -1;
if(pipe->ifinst->uinst == RT_NULL) return -1;
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);
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);
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);
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);
return hcd->ops->hub_ctrl(port, cmd, args);
}
#endif

View File

@ -17,10 +17,10 @@ if GetDepend('RT_USB_CLASS_MASS_STORAGE'):
src += Glob('class/mass.c')
src += Glob('udev/udisk.c')
if GetDepend('RT_USING_CLASS_HID'):
if GetDepend('RT_USB_CLASS_HID'):
src += Glob('class/hid.c')
if GetDepend('RT_USING_HID_MOUSE'):
if GetDepend('RT_USB_HID_MOUSE'):
src += Glob('udev/umouse.c')
if GetDepend('RT_USB_HID_KEYBOARD'):

View File

@ -20,52 +20,157 @@
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)
{
uadkinst_t adkinst;
rt_size_t length;
struct ureqest setup;
uinst_t uinst;
int timeout = 100;
/* parameter check */
RT_ASSERT(ifinst != RT_NULL);
RT_ASSERT(ifinst->uinst != RT_NULL);
RT_ASSERT(buffer != RT_NULL);
uinst = ifinst->uinst;
if(ifinst == RT_NULL)
{
rt_kprintf("the interface is not available\n");
return -RT_EIO;
}
/* get storage instance from the interface instance */
adkinst = (uadkinst_t)ifinst->user_data;
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;
/* send the cbw */
length = rt_usb_hcd_bulk_xfer(ifinst->uinst->hcd, adkinst->pipe_in,
buffer, size, 300);
return length;
if(rt_usb_hcd_control_xfer(uinst->hcd, uinst, &setup, (void*)protocol, 2,
timeout) == 0) return RT_EOK;
else return -RT_FALSE;
}
rt_err_t rt_usb_adk_write(uifinst_t ifinst, rt_uint8_t *buffer,
rt_size_t size)
/**
* 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)
{
uadkinst_t adkinst;
rt_size_t length;
struct ureqest setup;
uinst_t uinst;
int timeout = 100;
/* parameter check */
RT_ASSERT(ifinst != RT_NULL);
RT_ASSERT(ifinst->uinst != RT_NULL);
RT_ASSERT(buffer != RT_NULL);
uinst = ifinst->uinst;
if(ifinst == RT_NULL)
{
rt_kprintf("the interface is not available\n");
return -RT_EIO;
}
/* get storage instance from the interface instance */
adkinst = (uadkinst_t)ifinst->user_data;
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;
/* send the cbw */
length = rt_usb_hcd_bulk_xfer(ifinst->uinst->hcd, adkinst->pipe_out,
buffer, size, 300);
return length;
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;
rt_size_t length;
uifinst_t ifinst;
/* check parameter */
RT_ASSERT(device != RT_NULL);
RT_ASSERT(buffer != RT_NULL);
ifinst = (uifinst_t)device->user_data;
adkinst = (uadkinst_t)ifinst->user_data;
length = rt_usb_hcd_bulk_xfer(ifinst->uinst->hcd, adkinst->pipe_in,
buffer, size, 300);
return length;
}
/**
* 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;
rt_size_t length;
uifinst_t ifinst;
RT_ASSERT(buffer != RT_NULL);
ifinst = (uifinst_t)device->user_data;
adkinst = (uadkinst_t)ifinst->user_data;
length = rt_usb_hcd_bulk_xfer(ifinst->uinst->hcd, adkinst->pipe_out,
(void*)buffer, size, 300);
return length;
}
/**
@ -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)
{
int i = 0;
uadkinst_t adkinst;
uifinst_t ifinst = (uifinst_t)arg;
rt_err_t ret;
/* parameter check */
if(ifinst == RT_NULL)
{
rt_kprintf("the interface is not available\n");
return -RT_EIO;
}
int i = 0;
uadkinst_t adkinst;
uifinst_t ifinst = (uifinst_t)arg;
udev_desc_t dev_desc;
rt_uint16_t protocol;
rt_err_t ret;
/* parameter check */
if(ifinst == RT_NULL)
{
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_ASSERT(adkinst != RT_NULL);
RT_DEBUG_LOG(RT_DEBUG_USB,("rt_usb_adk_run\n"));
/* initilize the data structure */
rt_memset(adkinst, 0, sizeof(struct uadkinst));
ifinst->user_data = (void*)adkinst;
if(ifinst->intf_desc->bInterfaceSubClass != 0xFF) return -RT_ERROR;
dev_desc = &ifinst->uinst->dev_desc;
if(dev_desc->idVendor == USB_ACCESSORY_VENDOR_ID &&
(dev_desc->idProduct == USB_ACCESSORY_PRODUCT_ID ||
dev_desc->idProduct == USB_ACCESSORY_ADB_PRODUCT_ID))
{
rt_kprintf("found android accessory device\n");
}
else
{
rt_kprintf("switch device\n");
if((ret = rt_usb_adk_get_protocol(ifinst, &protocol)) != RT_EOK)
{
rt_kprintf("rt_usb_adk_get_protocol failed\n");
return ret;
}
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;
}
}
if(protocol != 1)
{
rt_kprintf("read protocol failed\n");
return -RT_ERROR;
}
/* check pipes infomation */
if(adkinst->pipe_in == RT_NULL || adkinst->pipe_out == RT_NULL)
{
rt_kprintf("pipe error, unsupported device\n");
return -RT_ERROR;
}
rt_usb_adk_send_string(ifinst, ACCESSORY_STRING_MANUFACTURER, "Real Thread, Inc");
rt_usb_adk_send_string(ifinst, ACCESSORY_STRING_MODEL, "ART");
rt_usb_adk_send_string(ifinst, ACCESSORY_STRING_DESCRIPTION, "Arduino like board");
rt_usb_adk_send_string(ifinst, ACCESSORY_STRING_VERSION, "1.0");
rt_usb_adk_send_string(ifinst, ACCESSORY_STRING_VERSION, "www.rt-thread.org");
rt_usb_adk_send_string(ifinst, ACCESSORY_STRING_SERIAL, "00000012345678");
return RT_EOK;
if((ret = rt_usb_adk_start(ifinst)) != RT_EOK)
{
rt_kprintf("rt_usb_adk_start failed\n");
return ret;
}
return RT_EOK;
}
adkinst = rt_malloc(sizeof(struct uadkinst));
RT_ASSERT(adkinst != RT_NULL);
/* initilize the data structure */
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)
*/
static rt_err_t rt_usb_adk_stop(void* arg)
{
uadkinst_t adkinst;
uifinst_t ifinst = (uifinst_t)arg;
uadkinst_t adkinst;
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;
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);
if(adkinst->pipe_in != RT_NULL)
rt_usb_hcd_free_pipe(ifinst->uinst->hcd, adkinst->pipe_in);
if(adkinst->pipe_out != RT_NULL)
rt_usb_hcd_free_pipe(ifinst->uinst->hcd, adkinst->pipe_out);
/* free adk instance */
if(adkinst != RT_NULL) rt_free(adkinst);
/* free interface instance */
if(ifinst != RT_NULL) rt_free(ifinst);
/* unregister adk device */
rt_device_unregister(&adkinst->device);
return RT_EOK;
/* free adk instance */
if(adkinst != RT_NULL) rt_free(adkinst);
/* free interface instance */
rt_free(ifinst);
return RT_EOK;
}
/**
@ -181,12 +356,12 @@ static rt_err_t rt_usb_adk_stop(void* arg)
*/
ucd_t rt_usb_class_driver_adk(void)
{
adk_driver.class_code = USB_CLASS_ADK;
adk_driver.run = rt_usb_adk_run;
adk_driver.stop = rt_usb_adk_stop;
adk_driver.class_code = USB_CLASS_ADK;
adk_driver.run = rt_usb_adk_run;
adk_driver.stop = rt_usb_adk_stop;
return &adk_driver;
return &adk_driver;
}
#endif

View File

@ -19,12 +19,29 @@
struct uadkinst
{
upipe_t pipe_in;
upipe_t pipe_out;
};
upipe_t pipe_in;
upipe_t pipe_out;
struct rt_device device;
};
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

View File

@ -27,33 +27,33 @@ static struct uinstance uinst[USB_MAX_DEVICE];
*/
uinst_t rt_usb_alloc_instance(void)
{
int i;
int i;
/* lock scheduler */
rt_enter_critical();
for(i=0; i<USB_MAX_DEVICE; i++)
{
/* to find an idle instance handle */
if(uinst[i].status != UINST_STATUS_IDLE) continue;
/* initialize the usb device instance */
rt_memset(&uinst[i], 0, sizeof(struct uinstance));
uinst[i].status = UINST_STATUS_BUSY;
uinst[i].index = i + 1;
uinst[i].address = 0;
uinst[i].max_packet_size = 0x8;
/* lock scheduler */
rt_enter_critical();
for(i=0; i<USB_MAX_DEVICE; i++)
{
/* to find an idle instance handle */
if(uinst[i].status != UINST_STATUS_IDLE) continue;
/* initialize the usb device instance */
rt_memset(&uinst[i], 0, sizeof(struct uinstance));
uinst[i].status = UINST_STATUS_BUSY;
uinst[i].index = i + 1;
uinst[i].address = 0;
uinst[i].max_packet_size = 0x8;
/* unlock scheduler */
rt_exit_critical();
return &uinst[i];
}
/* unlock scheduler */
rt_exit_critical();
return &uinst[i];
}
/* unlock scheduler */
rt_exit_critical();
/* unlock scheduler */
rt_exit_critical();
return RT_NULL;
return RT_NULL;
}
/**
@ -67,113 +67,123 @@ uinst_t rt_usb_alloc_instance(void)
*/
rt_err_t rt_usb_attatch_instance(uinst_t uinst)
{
int i = 0;
rt_err_t ret = RT_EOK;
struct uconfig_descriptor cfg_desc;
udev_desc_t dev_desc;
uintf_desc_t intf_desc;
ucd_t drv;
int i = 0;
rt_err_t ret = RT_EOK;
struct uconfig_descriptor cfg_desc;
udev_desc_t dev_desc;
uintf_desc_t intf_desc;
ucd_t drv;
RT_ASSERT(uinst != RT_NULL);
rt_memset(&cfg_desc, 0, sizeof(struct uconfig_descriptor));
dev_desc = &uinst->dev_desc;
RT_ASSERT(uinst != RT_NULL);
rt_memset(&cfg_desc, 0, sizeof(struct uconfig_descriptor));
dev_desc = &uinst->dev_desc;
/* get device descriptor head */
ret = rt_usb_get_descriptor(uinst, USB_DESC_TYPE_DEVICE, (void*)dev_desc, 8);
if(ret != RT_EOK)
{
rt_kprintf("get device descriptor head failed\n");
return ret;
}
/* set device address */
ret = rt_usb_set_address(uinst);
if(ret != RT_EOK)
{
rt_kprintf("set device address failed\n");
return ret;
}
RT_DEBUG_LOG(RT_DEBUG_USB, ("start enumnation\n"));
/* get device descriptor head */
ret = rt_usb_get_descriptor(uinst, USB_DESC_TYPE_DEVICE, (void*)dev_desc, 8);
if(ret != RT_EOK)
{
rt_kprintf("get device descriptor head failed\n");
return ret;
}
/* set device address */
ret = rt_usb_set_address(uinst);
if(ret != RT_EOK)
{
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 */
uinst->max_packet_size = uinst->dev_desc.bMaxPacketSize0;
RT_DEBUG_LOG(RT_DEBUG_USB, ("get device descriptor length %d\n",
dev_desc->bLength));
/* get full device descriptor again */
ret = rt_usb_get_descriptor
(uinst, USB_DESC_TYPE_DEVICE, (void*)dev_desc, dev_desc->bLength);
if(ret != RT_EOK)
{
rt_kprintf("get full device descriptor failed\n");
return ret;
}
RT_DEBUG_LOG(RT_DEBUG_USB, ("get device descriptor length %d\n",
dev_desc->bLength));
/* get full device descriptor again */
ret = rt_usb_get_descriptor
(uinst, USB_DESC_TYPE_DEVICE, (void*)dev_desc, dev_desc->bLength);
if(ret != RT_EOK)
{
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));
if(ret != RT_EOK)
{
rt_kprintf("get configuration descriptor head failed\n");
return ret;
}
RT_DEBUG_LOG(RT_DEBUG_USB, ("Vendor ID 0x%x\n", dev_desc->idVendor));
RT_DEBUG_LOG(RT_DEBUG_USB, ("Product ID 0x%x\n", dev_desc->idProduct));
/* alloc memory for configuration descriptor */
uinst->cfg_desc = (ucfg_desc_t)rt_malloc(cfg_desc.wTotalLength);
rt_memset(uinst->cfg_desc, 0, cfg_desc.wTotalLength);
/* get configuration descriptor head */
ret = rt_usb_get_descriptor(uinst, USB_DESC_TYPE_CONFIGURATION, &cfg_desc,
sizeof(struct uconfig_descriptor));
if(ret != RT_EOK)
{
rt_kprintf("get configuration descriptor head failed\n");
return ret;
}
/* get full configuration descriptor */
ret = rt_usb_get_descriptor(uinst, USB_DESC_TYPE_CONFIGURATION,
uinst->cfg_desc, cfg_desc.wTotalLength);
if(ret != RT_EOK)
{
rt_kprintf("get full configuration descriptor failed\n");
return ret;
}
/* alloc memory for configuration descriptor */
uinst->cfg_desc = (ucfg_desc_t)rt_malloc(cfg_desc.wTotalLength);
rt_memset(uinst->cfg_desc, 0, cfg_desc.wTotalLength);
/* set configuration */
ret = rt_usb_set_configure(uinst, 1);
if(ret != RT_EOK) return ret;
/* get full configuration descriptor */
ret = rt_usb_get_descriptor(uinst, USB_DESC_TYPE_CONFIGURATION,
uinst->cfg_desc, cfg_desc.wTotalLength);
if(ret != RT_EOK)
{
rt_kprintf("get full configuration descriptor failed\n");
return ret;
}
//for(i=0; i<uinst->cfg_desc->bNumInterfaces; i++)
{
/* get interface descriptor through configuration descriptor */
ret = rt_usb_get_interface_descriptor(uinst->cfg_desc, i, &intf_desc);
if(ret != RT_EOK)
{
rt_kprintf("rt_usb_get_interface_descriptor error\n");
return -RT_ERROR;
}
/* set configuration */
ret = rt_usb_set_configure(uinst, 1);
if(ret != RT_EOK) return ret;
/* find driver by class code found in interface descriptor */
drv = rt_usb_class_driver_find(intf_desc->bInterfaceClass,
intf_desc->bInterfaceSubClass);
if(drv != RT_NULL)
{
/* allocate memory for interface uinst */
uinst->ifinst[i] =
(uifinst_t)rt_malloc(sizeof(struct uifinst));
for(i=0; i<uinst->cfg_desc->bNumInterfaces; i++)
{
/* get interface descriptor through configuration descriptor */
ret = rt_usb_get_interface_descriptor(uinst->cfg_desc, i, &intf_desc);
if(ret != RT_EOK)
{
rt_kprintf("rt_usb_get_interface_descriptor error\n");
return -RT_ERROR;
}
uinst->ifinst[i]->drv = drv;
uinst->ifinst[i]->uinst = uinst;
uinst->ifinst[i]->intf_desc = intf_desc;
RT_DEBUG_LOG(RT_DEBUG_USB, ("interface class 0x%x, subclass 0x%x\n",
intf_desc->bInterfaceClass, intf_desc->bInterfaceSubClass));
/* open usb class driver */
ret = rt_usb_class_driver_run(drv, (void*)uinst->ifinst[i]);
if(ret != RT_EOK)
{
rt_kprintf("interface %d run class driver error\n", i);
}
}
else
{
rt_kprintf("find usb device driver failed\n");
return -RT_ERROR;
}
}
return RT_EOK;
/* find driver by class code found in interface descriptor */
drv = rt_usb_class_driver_find(intf_desc->bInterfaceClass,
intf_desc->bInterfaceSubClass);
if(drv != RT_NULL)
{
/* allocate memory for interface uinst */
uinst->ifinst[i] =
(uifinst_t)rt_malloc(sizeof(struct uifinst));
uinst->ifinst[i]->drv = drv;
uinst->ifinst[i]->uinst = uinst;
uinst->ifinst[i]->intf_desc = intf_desc;
uinst->ifinst[i]->user_data = RT_NULL;
/* open usb class driver */
ret = rt_usb_class_driver_run(drv, (void*)uinst->ifinst[i]);
if(ret != 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)
*/
rt_err_t rt_usb_detach_instance(uinst_t uinst)
{
int i = 0;
int i = 0;
if(uinst == RT_NULL)
{
rt_kprintf("no usb instance to detach\n");
return -RT_ERROR;
}
/* free configration descriptor */
if(uinst->cfg_desc) rt_free(uinst->cfg_desc);
for(i=0; i<uinst->cfg_desc->bNumInterfaces; i++)
{
if(uinst->ifinst[i] == RT_NULL) continue;
if(uinst->ifinst[i]->drv == RT_NULL) continue;
if(uinst == RT_NULL)
{
rt_kprintf("no usb instance to detach\n");
return -RT_ERROR;
}
/* free configration descriptor */
if(uinst->cfg_desc) rt_free(uinst->cfg_desc);
for(i=0; i<uinst->cfg_desc->bNumInterfaces; i++)
{
if(uinst->ifinst[i] == 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_usb_class_driver_stop(uinst->ifinst[i]->drv, (void*)uinst->ifinst[i]);
}
rt_memset(uinst, 0, sizeof(struct uinstance));
return RT_EOK;
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_memset(uinst, 0, sizeof(struct uinstance));
return RT_EOK;
}
/**
@ -224,23 +234,23 @@ rt_err_t rt_usb_detach_instance(uinst_t uinst)
* @return the error code, RT_EOK on successfully.
*/
rt_err_t rt_usb_get_descriptor(uinst_t uinst, rt_uint8_t type, void* buffer,
int nbytes)
int nbytes)
{
struct ureqest setup;
int timeout = 100;
RT_ASSERT(uinst != RT_NULL);
struct ureqest setup;
int timeout = 100;
RT_ASSERT(uinst != RT_NULL);
setup.request_type = USB_REQ_TYPE_DIR_IN | USB_REQ_TYPE_STANDARD |
USB_REQ_TYPE_DEVICE;
setup.request = USB_REQ_GET_DESCRIPTOR;
setup.index = 0;
setup.length = nbytes;
setup.value = type << 8;
setup.request_type = USB_REQ_TYPE_DIR_IN | USB_REQ_TYPE_STANDARD |
USB_REQ_TYPE_DEVICE;
setup.request = USB_REQ_GET_DESCRIPTOR;
setup.index = 0;
setup.length = nbytes;
setup.value = type << 8;
if(rt_usb_hcd_control_xfer(uinst->hcd, uinst, &setup, buffer, nbytes,
timeout) != nbytes) return -RT_EIO;
else return RT_EOK;
if(rt_usb_hcd_control_xfer(uinst->hcd, uinst, &setup, buffer, nbytes,
timeout) != nbytes) return -RT_EIO;
else return RT_EOK;
}
/**
@ -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)
{
struct ureqest setup;
int timeout = 100;
RT_ASSERT(uinst != RT_NULL);
struct ureqest setup;
int timeout = 100;
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 |
USB_REQ_TYPE_DEVICE;
setup.request = USB_REQ_SET_ADDRESS;
setup.index = 0;
setup.length = 0;
setup.value = uinst->index;
setup.request_type = USB_REQ_TYPE_DIR_OUT | USB_REQ_TYPE_STANDARD |
USB_REQ_TYPE_DEVICE;
setup.request = USB_REQ_SET_ADDRESS;
setup.index = 0;
setup.length = 0;
setup.value = uinst->index;
if(rt_usb_hcd_control_xfer(uinst->hcd, uinst, &setup, RT_NULL, 0,
timeout) != 0) return -RT_EIO;
if(rt_usb_hcd_control_xfer(uinst->hcd, uinst, &setup, RT_NULL, 0,
timeout) != 0) return -RT_EIO;
rt_thread_delay(50);
rt_thread_delay(50);
uinst->address = uinst->index;
return RT_EOK;
uinst->address = uinst->index;
return RT_EOK;
}
/**
@ -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)
{
struct ureqest setup;
int timeout = 100;
struct ureqest setup;
int timeout = 100;
/* check parameter */
RT_ASSERT(uinst != RT_NULL);
/* check parameter */
RT_ASSERT(uinst != RT_NULL);
setup.request_type = USB_REQ_TYPE_DIR_OUT | USB_REQ_TYPE_STANDARD |
USB_REQ_TYPE_DEVICE;
setup.request = USB_REQ_SET_CONFIGURATION;
setup.index = 0;
setup.length = 0;
setup.value = config;
setup.request_type = USB_REQ_TYPE_DIR_OUT | USB_REQ_TYPE_STANDARD |
USB_REQ_TYPE_DEVICE;
setup.request = USB_REQ_SET_CONFIGURATION;
setup.index = 0;
setup.length = 0;
setup.value = config;
if(rt_usb_hcd_control_xfer(uinst->hcd, uinst, &setup, RT_NULL, 0,
timeout) != 0) return -RT_EIO;
return RT_EOK;
if(rt_usb_hcd_control_xfer(uinst->hcd, uinst, &setup, RT_NULL, 0,
timeout) != 0) return -RT_EIO;
return RT_EOK;
}
/**
@ -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)
{
struct ureqest setup;
int timeout = 100;
struct ureqest setup;
int timeout = 100;
/* check parameter */
RT_ASSERT(uinst != RT_NULL);
/* check parameter */
RT_ASSERT(uinst != RT_NULL);
setup.request_type = USB_REQ_TYPE_DIR_OUT | USB_REQ_TYPE_STANDARD |
USB_REQ_TYPE_INTERFACE;
setup.request = USB_REQ_SET_INTERFACE;
setup.index = 0;
setup.length = 0;
setup.value = intf;
setup.request_type = USB_REQ_TYPE_DIR_OUT | USB_REQ_TYPE_STANDARD |
USB_REQ_TYPE_INTERFACE;
setup.request = USB_REQ_SET_INTERFACE;
setup.index = 0;
setup.length = 0;
setup.value = intf;
if(rt_usb_hcd_control_xfer(uinst->hcd, uinst, &setup, RT_NULL, 0,
timeout) != 0) return -RT_EIO;
return RT_EOK;
if(rt_usb_hcd_control_xfer(uinst->hcd, uinst, &setup, RT_NULL, 0,
timeout) != 0) return -RT_EIO;
return RT_EOK;
}
/**
@ -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)
{
struct ureqest setup;
int timeout = 100;
struct ureqest setup;
int timeout = 100;
/* check parameter */
RT_ASSERT(uinst != RT_NULL);
/* check parameter */
RT_ASSERT(uinst != RT_NULL);
setup.request_type = USB_REQ_TYPE_DIR_OUT | USB_REQ_TYPE_STANDARD |
USB_REQ_TYPE_ENDPOINT;
setup.request = USB_REQ_CLEAR_FEATURE;
setup.index = endpoint;
setup.length = 0;
setup.value = feature;
setup.request_type = USB_REQ_TYPE_DIR_OUT | USB_REQ_TYPE_STANDARD |
USB_REQ_TYPE_ENDPOINT;
setup.request = USB_REQ_CLEAR_FEATURE;
setup.index = endpoint;
setup.length = 0;
setup.value = feature;
if(rt_usb_hcd_control_xfer(uinst->hcd, uinst, &setup, RT_NULL, 0,
timeout) != 0) return -RT_EIO;
return RT_EOK;
if(rt_usb_hcd_control_xfer(uinst->hcd, uinst, &setup, RT_NULL, 0,
timeout) != 0) return -RT_EIO;
return RT_EOK;
}
/**
@ -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.
*/
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;
udesc_t desc;
rt_uint32_t ptr, depth = 0;
udesc_t desc;
/* check parameter */
RT_ASSERT(cfg_desc != RT_NULL);
/* check parameter */
RT_ASSERT(cfg_desc != RT_NULL);
ptr = (rt_uint32_t)cfg_desc + cfg_desc->bLength;
while(ptr < (rt_uint32_t)cfg_desc + cfg_desc->wTotalLength)
{
if(depth++ > 0x20)
{
*intf_desc = RT_NULL;
return -RT_EIO;
}
desc = (udesc_t)ptr;
if(desc->type == USB_DESC_TYPE_INTERFACE)
{
if(((uintf_desc_t)desc)->bInterfaceNumber == num)
{
*intf_desc = (uintf_desc_t)desc;
ptr = (rt_uint32_t)cfg_desc + cfg_desc->bLength;
while(ptr < (rt_uint32_t)cfg_desc + cfg_desc->wTotalLength)
{
if(depth++ > 0x20)
{
*intf_desc = RT_NULL;
return -RT_EIO;
}
desc = (udesc_t)ptr;
if(desc->type == USB_DESC_TYPE_INTERFACE)
{
if(((uintf_desc_t)desc)->bInterfaceNumber == num)
{
*intf_desc = (uintf_desc_t)desc;
RT_DEBUG_LOG(RT_DEBUG_USB,
("rt_usb_get_interface_descriptor: %d\n", num));
return RT_EOK;
}
}
ptr = (rt_uint32_t)desc + desc->bLength;
}
RT_DEBUG_LOG(RT_DEBUG_USB,
("rt_usb_get_interface_descriptor: %d\n", num));
return RT_EOK;
}
}
ptr = (rt_uint32_t)desc + desc->bLength;
}
rt_kprintf("rt_usb_get_interface_descriptor %d failed\n", num);
return -RT_EIO;
rt_kprintf("rt_usb_get_interface_descriptor %d failed\n", num);
return -RT_EIO;
}
/**
@ -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.
*/
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;
rt_uint32_t ptr;
udesc_t desc;
int count = 0, depth = 0;
rt_uint32_t ptr;
udesc_t desc;
/* check parameter */
RT_ASSERT(intf_desc != RT_NULL);
RT_ASSERT(num < intf_desc->bNumEndpoints);
/* check parameter */
RT_ASSERT(intf_desc != RT_NULL);
RT_ASSERT(num < intf_desc->bNumEndpoints);
ptr = (rt_uint32_t)intf_desc + intf_desc->bLength;
while(count < intf_desc->bNumEndpoints)
{
if(depth++ > 0x20)
{
*ep_desc = RT_NULL;
return -RT_EIO;
}
desc = (udesc_t)ptr;
if(desc->type == USB_DESC_TYPE_ENDPOINT)
{
if(num == count)
{
*ep_desc = (uep_desc_t)desc;
ptr = (rt_uint32_t)intf_desc + intf_desc->bLength;
while(count < intf_desc->bNumEndpoints)
{
if(depth++ > 0x20)
{
*ep_desc = RT_NULL;
return -RT_EIO;
}
desc = (udesc_t)ptr;
if(desc->type == USB_DESC_TYPE_ENDPOINT)
{
if(num == count)
{
*ep_desc = (uep_desc_t)desc;
RT_DEBUG_LOG(RT_DEBUG_USB,
("rt_usb_get_endpoint_descriptor: %d\n", num));
return RT_EOK;
}
else count++;
}
ptr = (rt_uint32_t)desc + desc->bLength;
}
RT_DEBUG_LOG(RT_DEBUG_USB,
("rt_usb_get_endpoint_descriptor: %d\n", num));
return RT_EOK;
}
else count++;
}
ptr = (rt_uint32_t)desc + desc->bLength;
}
rt_kprintf("rt_usb_get_endpoint_descriptor %d failed\n", num);
return -RT_EIO;
rt_kprintf("rt_usb_get_endpoint_descriptor %d failed\n", num);
return -RT_EIO;
}

View File

@ -25,9 +25,9 @@ static rt_list_t _driver_list;
*/
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)
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 */
rt_list_insert_after(&_driver_list, &(drv->list));
return RT_EOK;
/* insert class driver into driver list */
rt_list_insert_after(&_driver_list, &(drv->list));
return RT_EOK;
}
/**
@ -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_ASSERT(drv != RT_NULL);
RT_ASSERT(drv != RT_NULL);
/* remove class driver from driver list */
rt_list_remove(&(drv->list));
/* remove class driver from driver 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)
*/
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)
drv->run(args);
if(drv->run != RT_NULL)
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)
*/
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)
drv->stop(args);
if(drv->stop != RT_NULL)
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)
*/
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 */
if (rt_thread_self() != RT_NULL)
rt_enter_critical();
/* enter critical */
if (rt_thread_self() != RT_NULL)
rt_enter_critical();
/* try to find driver object */
for (node = _driver_list.next; node != &_driver_list; node = node->next)
{
ucd_t drv =
(ucd_t)rt_list_entry(node, struct uclass_driver, list);
if (drv->class_code == class_code)
{
/* leave critical */
if (rt_thread_self() != RT_NULL)
rt_exit_critical();
/* try to find driver object */
for (node = _driver_list.next; node != &_driver_list; node = node->next)
{
ucd_t drv =
(ucd_t)rt_list_entry(node, struct uclass_driver, list);
if (drv->class_code == class_code)
{
/* leave critical */
if (rt_thread_self() != RT_NULL)
rt_exit_critical();
return drv;
}
}
return drv;
}
}
/* leave critical */
if (rt_thread_self() != RT_NULL)
rt_exit_critical();
/* leave critical */
if (rt_thread_self() != RT_NULL)
rt_exit_critical();
/* not found */
return RT_NULL;
/* not found */
return RT_NULL;
}

View File

@ -15,7 +15,7 @@
#include <rtthread.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 uclass_driver hub_driver;
@ -31,24 +31,24 @@ static struct uclass_driver hub_driver;
* @return the error code, RT_EOK on successfully.
*/
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;
int timeout = 100;
/* parameter check */
RT_ASSERT(uinst != RT_NULL);
setup.request_type = USB_REQ_TYPE_DIR_IN | USB_REQ_TYPE_CLASS |
USB_REQ_TYPE_DEVICE;
setup.request = USB_REQ_GET_DESCRIPTOR;
setup.index = 0;
setup.length = nbytes;
setup.value = USB_DESC_TYPE_HUB << 8;
struct ureqest setup;
int timeout = 100;
/* parameter check */
RT_ASSERT(uinst != RT_NULL);
setup.request_type = USB_REQ_TYPE_DIR_IN | USB_REQ_TYPE_CLASS |
USB_REQ_TYPE_DEVICE;
setup.request = USB_REQ_GET_DESCRIPTOR;
setup.index = 0;
setup.length = nbytes;
setup.value = USB_DESC_TYPE_HUB << 8;
if(rt_usb_hcd_control_xfer(uinst->hcd, uinst, &setup, buffer, nbytes,
timeout) == nbytes) return RT_EOK;
else return -RT_FALSE;
if(rt_usb_hcd_control_xfer(uinst->hcd, uinst, &setup, buffer, nbytes,
timeout) == nbytes) return RT_EOK;
else return -RT_FALSE;
}
/**
@ -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)
{
struct ureqest setup;
int timeout = 100;
int length = 4;
/* parameter check */
RT_ASSERT(uinst != RT_NULL);
struct ureqest setup;
int timeout = 100;
int length = 4;
/* parameter check */
RT_ASSERT(uinst != RT_NULL);
setup.request_type = USB_REQ_TYPE_DIR_IN | USB_REQ_TYPE_CLASS |
USB_REQ_TYPE_DEVICE;
setup.request = USB_REQ_GET_STATUS;
setup.index = 0;
setup.length = length;
setup.value = 0;
setup.request_type = USB_REQ_TYPE_DIR_IN | USB_REQ_TYPE_CLASS |
USB_REQ_TYPE_DEVICE;
setup.request = USB_REQ_GET_STATUS;
setup.index = 0;
setup.length = length;
setup.value = 0;
if(rt_usb_hcd_control_xfer(uinst->hcd, uinst, &setup, buffer, length,
timeout) == length) return RT_EOK;
else return -RT_FALSE;
if(rt_usb_hcd_control_xfer(uinst->hcd, uinst, &setup, buffer, length,
timeout) == length) return RT_EOK;
else return -RT_FALSE;
}
/**
@ -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.
*/
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;
int timeout = 100;
int length = 4;
/* parameter check */
RT_ASSERT(uhub != RT_NULL);
struct ureqest setup;
int timeout = 100;
int length = 4;
/* parameter check */
RT_ASSERT(uhub != RT_NULL);
/* get roothub port status */
if(uhub->is_roothub)
{
rt_usb_hcd_hub_control(uhub->hcd, port, RH_GET_PORT_STATUS,
(void*)buffer);
return RT_EOK;
}
/* get roothub port status */
if(uhub->is_roothub)
{
rt_usb_hcd_hub_control(uhub->hcd, port, RH_GET_PORT_STATUS,
(void*)buffer);
return RT_EOK;
}
setup.request_type = USB_REQ_TYPE_DIR_IN | USB_REQ_TYPE_CLASS |
USB_REQ_TYPE_OTHER;
setup.request = USB_REQ_GET_STATUS;
setup.index = port;
setup.length = 4;
setup.value = 0;
setup.request_type = USB_REQ_TYPE_DIR_IN | USB_REQ_TYPE_CLASS |
USB_REQ_TYPE_OTHER;
setup.request = USB_REQ_GET_STATUS;
setup.index = port;
setup.length = 4;
setup.value = 0;
if(rt_usb_hcd_control_xfer(uhub->hcd, uhub->self, &setup, buffer,
length, timeout) == timeout) return RT_EOK;
else return -RT_FALSE;
if(rt_usb_hcd_control_xfer(uhub->hcd, uhub->self, &setup, buffer,
length, timeout) == timeout) return RT_EOK;
else return -RT_FALSE;
}
/**
@ -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.
*/
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;
int timeout = 100;
/* parameter check */
RT_ASSERT(uhub != RT_NULL);
struct ureqest setup;
int timeout = 100;
/* parameter check */
RT_ASSERT(uhub != RT_NULL);
/* clear roothub feature */
if(uhub->is_roothub)
{
rt_usb_hcd_hub_control(uhub->hcd, port, RH_CLEAR_PORT_FEATURE,
(void*)feature);
return RT_EOK;
}
/* clear roothub feature */
if(uhub->is_roothub)
{
rt_usb_hcd_hub_control(uhub->hcd, port, RH_CLEAR_PORT_FEATURE,
(void*)feature);
return RT_EOK;
}
setup.request_type = USB_REQ_TYPE_DIR_OUT | USB_REQ_TYPE_CLASS |
USB_REQ_TYPE_OTHER;
setup.request = USB_REQ_CLEAR_FEATURE;
setup.index = port;
setup.length = 0;
setup.value = feature;
setup.request_type = USB_REQ_TYPE_DIR_OUT | USB_REQ_TYPE_CLASS |
USB_REQ_TYPE_OTHER;
setup.request = USB_REQ_CLEAR_FEATURE;
setup.index = port;
setup.length = 0;
setup.value = feature;
if(rt_usb_hcd_control_xfer(uhub->hcd, uhub->self, &setup, RT_NULL, 0,
timeout) == 0) return RT_EOK;
else return -RT_FALSE;
if(rt_usb_hcd_control_xfer(uhub->hcd, uhub->self, &setup, RT_NULL, 0,
timeout) == 0) return RT_EOK;
else return -RT_FALSE;
}
/**
@ -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.
*/
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;
int timeout = 100;
/* parameter check */
RT_ASSERT(uhub != RT_NULL);
struct ureqest setup;
int timeout = 100;
/* parameter check */
RT_ASSERT(uhub != RT_NULL);
/* clear roothub feature */
if(uhub->is_roothub)
{
rt_usb_hcd_hub_control(uhub->hcd, port, RH_SET_PORT_FEATURE,
(void*)feature);
return RT_EOK;
}
/* clear roothub feature */
if(uhub->is_roothub)
{
rt_usb_hcd_hub_control(uhub->hcd, port, RH_SET_PORT_FEATURE,
(void*)feature);
return RT_EOK;
}
setup.request_type = USB_REQ_TYPE_DIR_OUT | USB_REQ_TYPE_CLASS |
USB_REQ_TYPE_OTHER;
setup.request = USB_REQ_SET_FEATURE;
setup.index = port;
setup.length = 0;
setup.value = feature;
setup.request_type = USB_REQ_TYPE_DIR_OUT | USB_REQ_TYPE_CLASS |
USB_REQ_TYPE_OTHER;
setup.request = USB_REQ_SET_FEATURE;
setup.index = port;
setup.length = 0;
setup.value = feature;
if(rt_usb_hcd_control_xfer(uhub->hcd, uhub->self, &setup, RT_NULL, 0,
timeout) == 0) return RT_EOK;
else return -RT_FALSE;
if(rt_usb_hcd_control_xfer(uhub->hcd, uhub->self, &setup, RT_NULL, 0,
timeout) == 0) return RT_EOK;
else return -RT_FALSE;
}
/**
@ -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 ret;
rt_uint32_t pstatus;
/* parameter check */
RT_ASSERT(uhub != RT_NULL);
rt_thread_delay(50);
rt_err_t ret;
rt_uint32_t pstatus;
/* parameter check */
RT_ASSERT(uhub != RT_NULL);
rt_thread_delay(50);
/* reset hub port */
ret = rt_usb_hub_set_port_feature(uhub, port, PORT_FEAT_RESET);
if(ret != RT_EOK) return ret;
/* reset hub port */
ret = rt_usb_hub_set_port_feature(uhub, port, PORT_FEAT_RESET);
if(ret != RT_EOK) return ret;
while(1)
{
ret = rt_usb_hub_get_port_status(uhub, port, (rt_uint8_t*)&pstatus);
if(!(pstatus & PORT_PRS)) break;
}
/* clear port reset feature */
ret = rt_usb_hub_clear_port_feature(uhub, port, PORT_FEAT_C_RESET);
if(ret != RT_EOK) return ret;
while(1)
{
ret = rt_usb_hub_get_port_status(uhub, port, (rt_uint8_t*)&pstatus);
if(!(pstatus & PORT_PRS)) break;
}
/* clear port reset feature */
ret = rt_usb_hub_clear_port_feature(uhub, port, PORT_FEAT_C_RESET);
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)
*/
rt_err_t rt_usb_hub_port_debounce(uhubinst_t uhub, rt_uint16_t port)
{
rt_err_t ret;
int i = 0, times = 20;
rt_uint32_t pstatus;
rt_bool_t connect = RT_TRUE;
rt_err_t ret;
int i = 0, times = 20;
rt_uint32_t pstatus;
rt_bool_t connect = RT_TRUE;
/* parameter check */
RT_ASSERT(uhub != RT_NULL);
/* parameter check */
RT_ASSERT(uhub != RT_NULL);
for(i=0; i<times; i++)
{
ret = rt_usb_hub_get_port_status(uhub, port, (rt_uint8_t*)&pstatus);
if(ret != RT_EOK) return ret;
if(!(pstatus & PORT_CCS))
{
connect = RT_FALSE;
break;
}
rt_thread_delay(1);
}
for(i=0; i<times; i++)
{
ret = rt_usb_hub_get_port_status(uhub, port, (rt_uint8_t*)&pstatus);
if(ret != RT_EOK) return ret;
if(!(pstatus & PORT_CCS))
{
connect = RT_FALSE;
break;
}
rt_thread_delay(1);
}
if(connect) return RT_EOK;
else return -RT_ERROR;
if(connect) return RT_EOK;
else return -RT_ERROR;
}
/**
@ -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)
{
int i;
rt_bool_t reconnect;
int i;
rt_bool_t reconnect;
/* parameter check */
RT_ASSERT(uhub != RT_NULL);
/* parameter check */
RT_ASSERT(uhub != RT_NULL);
/* get usb device instance */
for (i = 0; i < uhub->num_ports; i++)
{
rt_err_t ret;
uinst_t uinst;
rt_uint32_t pstatus = 0;
/* get usb device instance */
for (i = 0; i < uhub->num_ports; i++)
{
rt_err_t ret;
uinst_t uinst;
rt_uint32_t pstatus = 0;
reconnect = RT_FALSE;
/* get hub port status */
ret = rt_usb_hub_get_port_status(uhub, i + 1, (rt_uint8_t*)&pstatus);
if(ret != RT_EOK) continue;
reconnect = RT_FALSE;
/* get hub port status */
ret = rt_usb_hub_get_port_status(uhub, i + 1, (rt_uint8_t*)&pstatus);
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 */
if ((pstatus & PORT_CCSC))
{
/* clear port status change feature */
rt_usb_hub_clear_port_feature(uhub, i + 1, PORT_FEAT_C_CONNECTION);
reconnect = RT_TRUE;
}
/* check port status change */
if ((pstatus & PORT_CCSC))
{
/* clear port status change feature */
rt_usb_hub_clear_port_feature(uhub, i + 1, PORT_FEAT_C_CONNECTION);
reconnect = RT_TRUE;
}
if(pstatus & PORT_PESC)
{
rt_usb_hub_clear_port_feature(uhub, i + 1, PORT_FEAT_C_ENABLE);
reconnect = RT_TRUE;
}
if(reconnect)
{
if(uhub->child[i])
rt_usb_detach_instance(uhub->child[i]);
ret = rt_usb_hub_port_debounce(uhub, i + 1);
if(ret != RT_EOK) continue;
/* allocate an usb instance for new connected device */
uinst = rt_usb_alloc_instance();
if(uinst == RT_NULL) break;
/* set usb device speed */
uinst->speed = (pstatus & PORT_LSDA) ? 1 : 0;
uinst->parent = uhub;
uinst->hcd = uhub->hcd;
uhub->child[i] = uinst;
if(pstatus & PORT_PESC)
{
rt_usb_hub_clear_port_feature(uhub, i + 1, PORT_FEAT_C_ENABLE);
reconnect = RT_TRUE;
}
if(reconnect)
{
if(uhub->child[i]->status != UINST_STATUS_IDLE)
rt_usb_detach_instance(uhub->child[i]);
ret = rt_usb_hub_port_debounce(uhub, i + 1);
if(ret != RT_EOK) continue;
/* allocate an usb instance for new connected device */
uinst = rt_usb_alloc_instance();
if(uinst == RT_NULL) break;
/* set usb device speed */
uinst->speed = (pstatus & PORT_LSDA) ? 1 : 0;
uinst->parent = uhub;
uinst->hcd = uhub->hcd;
uhub->child[i] = uinst;
/* reset usb roothub port */
rt_usb_hub_reset_port(uhub, i + 1);
/* attatch the usb instance to the hcd */
rt_usb_attatch_instance(uinst);
}
}
/* reset usb roothub port */
rt_usb_hub_reset_port(uhub, i + 1);
/* attatch the usb instance to the hcd */
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)
*/
static void rt_usb_hub_irq(void* context)
{
upipe_t pipe;
uifinst_t ifinst;
uhubinst_t uhub;
int timeout = 100;
RT_ASSERT(context != RT_NULL);
pipe = (upipe_t)context;
ifinst = pipe->ifinst;
uhub = (uhubinst_t)ifinst->user_data;
upipe_t pipe;
uifinst_t ifinst;
uhubinst_t uhub;
int timeout = 100;
RT_ASSERT(context != RT_NULL);
pipe = (upipe_t)context;
ifinst = pipe->ifinst;
uhub = (uhubinst_t)ifinst->user_data;
if(pipe->status != UPIPE_STATUS_OK)
{
rt_kprintf("hub irq error\n");
return;
}
rt_usb_hub_port_change(uhub);
if(pipe->status != UPIPE_STATUS_OK)
{
rt_kprintf("hub irq error\n");
return;
}
rt_usb_hub_port_change(uhub);
rt_kprintf("hub int xfer...\n");
rt_kprintf("hub int xfer...\n");
/* parameter check */
RT_ASSERT(pipe->ifinst->uinst->hcd != RT_NULL);
rt_usb_hcd_int_xfer(ifinst->uinst->hcd, pipe, uhub->buffer,
pipe->ep.wMaxPacketSize, timeout);
/* parameter check */
RT_ASSERT(pipe->ifinst->uinst->hcd != RT_NULL);
rt_usb_hcd_int_xfer(ifinst->uinst->hcd, pipe, uhub->buffer,
pipe->ep.wMaxPacketSize, timeout);
}
/**
@ -393,90 +393,90 @@ static void rt_usb_hub_irq(void* context)
*/
static rt_err_t rt_usb_hub_run(void *arg)
{
int i = 0;
rt_err_t ret = RT_EOK;
uep_desc_t ep_desc;
uhubinst_t uhub;
uinst_t uinst;
uifinst_t ifinst = (uifinst_t)arg;
int timeout = 300;
int i = 0;
rt_err_t ret = RT_EOK;
uep_desc_t ep_desc;
uhubinst_t uhub;
uinst_t uinst;
uifinst_t ifinst = (uifinst_t)arg;
int timeout = 300;
/* paremeter check */
RT_ASSERT(ifinst != RT_NULL);
RT_DEBUG_LOG(RT_DEBUG_USB, ("rt_usb_hub_run\n"));
/* paremeter check */
RT_ASSERT(ifinst != RT_NULL);
RT_DEBUG_LOG(RT_DEBUG_USB, ("rt_usb_hub_run\n"));
/* get usb device instance */
uinst = ifinst->uinst;
/* get usb device instance */
uinst = ifinst->uinst;
/* create a hub instance */
uhub = rt_malloc(sizeof(struct uhubinst));
rt_memset(uhub, 0, sizeof(struct uhubinst));
/* make interface instance's user data point to hub instance */
ifinst->user_data = (void*)uhub;
/* create a hub instance */
uhub = rt_malloc(sizeof(struct uhubinst));
rt_memset(uhub, 0, sizeof(struct uhubinst));
/* make interface instance's user data point to hub instance */
ifinst->user_data = (void*)uhub;
/* get hub descriptor head */
ret = rt_usb_hub_get_descriptor(uinst, (rt_uint8_t*)&uhub->hub_desc, 8);
if(ret != RT_EOK)
{
rt_kprintf("get hub descriptor failed\n");
return -RT_ERROR;
}
/* get hub descriptor head */
ret = rt_usb_hub_get_descriptor(uinst, (rt_uint8_t*)&uhub->hub_desc, 8);
if(ret != RT_EOK)
{
rt_kprintf("get hub descriptor failed\n");
return -RT_ERROR;
}
/* get full hub descriptor */
ret = rt_usb_hub_get_descriptor(uinst, (rt_uint8_t*)&uhub->hub_desc,
uhub->hub_desc.length);
if(ret != RT_EOK)
{
rt_kprintf("get hub descriptor again failed\n");
return -RT_ERROR;
}
/* get full hub descriptor */
ret = rt_usb_hub_get_descriptor(uinst, (rt_uint8_t*)&uhub->hub_desc,
uhub->hub_desc.length);
if(ret != RT_EOK)
{
rt_kprintf("get hub descriptor again failed\n");
return -RT_ERROR;
}
/* get hub ports number */
uhub->num_ports = uhub->hub_desc.num_ports;
uhub->hcd = uinst->hcd;
uhub->self = uinst;
/* get hub ports number */
uhub->num_ports = uhub->hub_desc.num_ports;
uhub->hcd = uinst->hcd;
uhub->self = uinst;
/* reset all hub ports */
for (i = 0; i < uhub->num_ports; i++)
{
rt_usb_hub_set_port_feature(uhub, i + 1, PORT_FEAT_POWER);
rt_thread_delay(uhub->hub_desc.pwron_to_good
* 2 * RT_TICK_PER_SECOND / 1000 );
}
/* reset all hub ports */
for (i = 0; i < uhub->num_ports; i++)
{
rt_usb_hub_set_port_feature(uhub, i + 1, PORT_FEAT_POWER);
rt_thread_delay(uhub->hub_desc.pwron_to_good
* 2 * RT_TICK_PER_SECOND / 1000 );
}
if(ifinst->intf_desc->bNumEndpoints != 1)
return -RT_ERROR;
if(ifinst->intf_desc->bNumEndpoints != 1)
return -RT_ERROR;
/* get endpoint descriptor from interface descriptor */
rt_usb_get_endpoint_descriptor(ifinst->intf_desc, 0, &ep_desc);
if(ep_desc == RT_NULL)
{
rt_kprintf("rt_usb_get_endpoint_descriptor error\n");
return -RT_ERROR;
}
/* get endpoint descriptor from interface descriptor */
rt_usb_get_endpoint_descriptor(ifinst->intf_desc, 0, &ep_desc);
if(ep_desc == RT_NULL)
{
rt_kprintf("rt_usb_get_endpoint_descriptor error\n");
return -RT_ERROR;
}
/* the endpoint type of hub class should be interrupt */
if( USB_EP_ATTR(ep_desc->bmAttributes) == USB_EP_ATTR_INT)
{
/* the endpoint direction of hub class should be in */
if(ep_desc->bEndpointAddress & USB_DIR_IN)
{
/* allocate a pipe according to the endpoint type */
rt_usb_hcd_alloc_pipe(uinst->hcd, &uhub->pipe_in, ifinst,
ep_desc, rt_usb_hub_irq);
}
else return -RT_ERROR;
}
/* the endpoint type of hub class should be interrupt */
if( USB_EP_ATTR(ep_desc->bmAttributes) == USB_EP_ATTR_INT)
{
/* the endpoint direction of hub class should be in */
if(ep_desc->bEndpointAddress & USB_DIR_IN)
{
/* allocate a pipe according to the endpoint type */
rt_usb_hcd_alloc_pipe(uinst->hcd, &uhub->pipe_in, ifinst,
ep_desc, rt_usb_hub_irq);
}
else return -RT_ERROR;
}
/* parameter check */
RT_ASSERT(uinst->hcd != RT_NULL);
rt_usb_hcd_int_xfer(uinst->hcd, uhub->pipe_in, uhub->buffer,
uhub->pipe_in->ep.wMaxPacketSize, timeout);
return RT_EOK;
/* parameter check */
RT_ASSERT(uinst->hcd != RT_NULL);
rt_usb_hcd_int_xfer(uinst->hcd, uhub->pipe_in, uhub->buffer,
uhub->pipe_in->ep.wMaxPacketSize, timeout);
return RT_EOK;
}
/**
@ -489,32 +489,32 @@ static rt_err_t rt_usb_hub_run(void *arg)
*/
static rt_err_t rt_usb_hub_stop(void* arg)
{
int i;
uhubinst_t uhub;
uinst_t uinst;
uifinst_t ifinst = (uifinst_t)arg;
int i;
uhubinst_t uhub;
uinst_t uinst;
uifinst_t ifinst = (uifinst_t)arg;
/* paremeter check */
RT_ASSERT(ifinst != RT_NULL);
/* paremeter check */
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;
uhub = (uhubinst_t)ifinst->user_data;
uinst = ifinst->uinst;
uhub = (uhubinst_t)ifinst->user_data;
if(uhub->pipe_in != RT_NULL)
rt_usb_hcd_free_pipe(uinst->hcd, uhub->pipe_in);
if(uhub->pipe_in != RT_NULL)
rt_usb_hcd_free_pipe(uinst->hcd, uhub->pipe_in);
for(i=0; i<uhub->num_ports; i++)
{
if(uhub->child[i] != RT_NULL)
rt_usb_detach_instance(uhub->child[i]);
}
if(uhub != RT_NULL) rt_free(uhub);
if(ifinst != RT_NULL) rt_free(ifinst);
for(i=0; i<uhub->num_ports; i++)
{
if(uhub->child[i] != RT_NULL)
rt_usb_detach_instance(uhub->child[i]);
}
if(uhub != RT_NULL) rt_free(uhub);
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)
* @return the error code, RT_EOK on successfully.
*/
ucd_t rt_usb_class_driver_hub(void)
{
hub_driver.class_code = USB_CLASS_HUB;
hub_driver.run = rt_usb_hub_run;
hub_driver.stop = rt_usb_hub_stop;
{
hub_driver.class_code = USB_CLASS_HUB;
hub_driver.run = rt_usb_hub_run;
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)
* @return none.
*/
static void rt_usb_hub_thread_entry(void* parameter)
{
while(1)
{
struct umsg msg;
/* receive message */
if(rt_mq_recv(usb_mq, &msg, sizeof(struct umsg), RT_WAITING_FOREVER)
!= RT_EOK ) continue;
{
while(1)
{
struct umsg msg;
/* receive message */
if(rt_mq_recv(usb_mq, &msg, sizeof(struct umsg), RT_WAITING_FOREVER)
!= RT_EOK ) continue;
RT_DEBUG_LOG(RT_DEBUG_USB, ("msg type %d\n", msg.type));
switch (msg.type)
{
case USB_MSG_CONNECT_CHANGE:
rt_usb_hub_port_change(msg.content.uhub);
break;
case USB_MSG_CALLBACK:
/* invoke callback */
msg.content.cb.function(msg.content.cb.context);
break;
default:
break;
}
}
RT_DEBUG_LOG(RT_DEBUG_USB, ("msg type %d\n", msg.type));
switch (msg.type)
{
case USB_MSG_CONNECT_CHANGE:
rt_usb_hub_port_change(msg.content.uhub);
break;
case USB_MSG_CALLBACK:
/* invoke callback */
msg.content.cb.function(msg.content.cb.context);
break;
default:
break;
}
}
}
/**
@ -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_ASSERT(msg != RT_NULL);
RT_ASSERT(msg != RT_NULL);
/* send message to usb message queue */
rt_mq_send(usb_mq, (void*)msg, size);
/* send message to usb message queue */
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)
*/
void rt_usb_hub_thread(void)
{
rt_thread_t thread;
/* create usb message queue */
usb_mq = rt_mq_create("usbh", 32, 16, RT_IPC_FLAG_FIFO);
/* create usb hub thread */
thread = rt_thread_create("usbh", rt_usb_hub_thread_entry, RT_NULL,
USB_THREAD_STACK_SIZE, 8, 20);
if(thread != RT_NULL)
{
/* startup usb host thread */
rt_thread_startup(thread);
}
rt_thread_t thread;
/* create usb message queue */
usb_mq = rt_mq_create("usbh", 32, 16, RT_IPC_FLAG_FIFO);
/* create usb hub thread */
thread = rt_thread_create("usbh", rt_usb_hub_thread_entry, RT_NULL,
USB_THREAD_STACK_SIZE, 8, 20);
if(thread != RT_NULL)
{
/* startup usb host thread */
rt_thread_startup(thread);
}
}