[host first]
This commit is contained in:
parent
dcb0f280b4
commit
b42fc96408
|
@ -45,6 +45,9 @@ extern "C" {
|
|||
#define UPIPE_STATUS_STALL 0x01
|
||||
#define UPIPE_STATUS_ERROR 0x02
|
||||
|
||||
#define USBH_PID_SETUP 0x00
|
||||
#define USBH_PID_DATA 0x01
|
||||
|
||||
struct uhcd;
|
||||
struct uintf;
|
||||
struct uhub;
|
||||
|
@ -74,10 +77,15 @@ typedef struct uprotocal* uprotocal_t;
|
|||
|
||||
struct uinstance
|
||||
{
|
||||
struct rt_device parent;
|
||||
|
||||
struct udevice_descriptor dev_desc;
|
||||
ucfg_desc_t cfg_desc;
|
||||
struct uhcd *hcd;
|
||||
|
||||
upipe_t pipe_ep0_out;
|
||||
upipe_t pipe_ep0_in;
|
||||
|
||||
rt_uint8_t status;
|
||||
rt_uint8_t type;
|
||||
rt_uint8_t index;
|
||||
|
@ -86,12 +94,12 @@ struct uinstance
|
|||
rt_uint8_t max_packet_size;
|
||||
rt_uint8_t port;
|
||||
|
||||
struct uhub* parent;
|
||||
struct uintf* intf[USB_MAX_INTERFACE];
|
||||
struct uhub* parent_hub;
|
||||
struct uhintf* intf[USB_MAX_INTERFACE];
|
||||
};
|
||||
typedef struct uinstance* uinst_t;
|
||||
|
||||
struct uintf
|
||||
struct uhintf
|
||||
{
|
||||
struct uinstance* device;
|
||||
uintf_desc_t intf_desc;
|
||||
|
@ -102,9 +110,10 @@ struct uintf
|
|||
|
||||
struct upipe
|
||||
{
|
||||
rt_uint8_t pipe_index;
|
||||
rt_uint32_t status;
|
||||
struct uendpoint_descriptor ep;
|
||||
struct uintf* intf;
|
||||
struct uhintf* intf;
|
||||
func_callback callback;
|
||||
void* user_data;
|
||||
};
|
||||
|
@ -127,23 +136,16 @@ typedef struct uhub* uhub_t;
|
|||
|
||||
struct uhcd_ops
|
||||
{
|
||||
int (*ctl_xfer)(struct uinstance* 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, struct uintf* intf, uep_desc_t ep,
|
||||
func_callback callback);
|
||||
int (*pipe_xfer) (upipe_t pipe, rt_uint8_t token, void* buffer, int nbytes, int timeout);
|
||||
rt_err_t (*alloc_pipe) (struct upipe* pipe, uep_desc_t ep);
|
||||
rt_err_t (*free_pipe) (upipe_t pipe);
|
||||
rt_err_t (*hub_ctrl)(rt_uint16_t port, rt_uint8_t cmd, void *args);
|
||||
};
|
||||
|
||||
typedef struct uhcd_ops* uhcd_ops_t;
|
||||
struct uhcd
|
||||
{
|
||||
struct rt_device parent;
|
||||
struct uhcd_ops* ops;
|
||||
struct uhub* roothub;
|
||||
uhcd_ops_t ops;
|
||||
uhub_t roothub;
|
||||
};
|
||||
typedef struct uhcd* uhcd_t;
|
||||
|
||||
|
@ -177,16 +179,13 @@ void rt_usbh_hub_init(void);
|
|||
struct uinstance* rt_usbh_alloc_instance(void);
|
||||
rt_err_t rt_usbh_attatch_instance(struct uinstance* device);
|
||||
rt_err_t rt_usbh_detach_instance(struct uinstance* device);
|
||||
rt_err_t rt_usbh_get_descriptor(struct uinstance* device, rt_uint8_t type, void* buffer,
|
||||
int nbytes);
|
||||
rt_err_t rt_usbh_get_descriptor(struct uinstance* device, rt_uint8_t type, void* buffer, int nbytes);
|
||||
rt_err_t rt_usbh_set_configure(struct uinstance* device, int config);
|
||||
rt_err_t rt_usbh_set_address(struct uinstance* device);
|
||||
rt_err_t rt_usbh_set_interface(struct uinstance* device, int intf);
|
||||
rt_err_t rt_usbh_clear_feature(struct uinstance* device, int endpoint, int feature);
|
||||
rt_err_t rt_usbh_get_interface_descriptor(ucfg_desc_t cfg_desc, int num,
|
||||
uintf_desc_t* intf_desc);
|
||||
rt_err_t rt_usbh_get_endpoint_descriptor(uintf_desc_t intf_desc, int num,
|
||||
uep_desc_t* ep_desc);
|
||||
rt_err_t rt_usbh_get_interface_descriptor(ucfg_desc_t cfg_desc, int num, uintf_desc_t* intf_desc);
|
||||
rt_err_t rt_usbh_get_endpoint_descriptor(uintf_desc_t intf_desc, int num, uep_desc_t* ep_desc);
|
||||
|
||||
/* usb class driver interface */
|
||||
rt_err_t rt_usbh_class_driver_init(void);
|
||||
|
@ -197,19 +196,10 @@ rt_err_t rt_usbh_class_driver_disable(ucd_t drv, void* args);
|
|||
ucd_t rt_usbh_class_driver_find(int class_code, int subclass_code);
|
||||
|
||||
/* usb class driver implement */
|
||||
ucd_t rt_usbh_class_driver_hid(void);
|
||||
ucd_t rt_usbh_class_driver_hub(void);
|
||||
ucd_t rt_usbh_class_driver_storage(void);
|
||||
ucd_t rt_usbh_class_driver_adk(void);
|
||||
|
||||
/* usb hid protocal implement */
|
||||
uprotocal_t rt_usbh_hid_protocal_kbd(void);
|
||||
uprotocal_t rt_usbh_hid_protocal_mouse(void);
|
||||
|
||||
/* usb adk class driver interface */
|
||||
rt_err_t rt_usbh_adk_set_string(const char* manufacturer, const char* model,
|
||||
const char* description, const char* version, const char* uri,
|
||||
const char* serial);
|
||||
|
||||
/* usb hub interface */
|
||||
rt_err_t rt_usbh_hub_get_descriptor(struct uinstance* device, rt_uint8_t *buffer,
|
||||
|
@ -225,57 +215,24 @@ rt_err_t rt_usbh_hub_reset_port(uhub_t uhub, rt_uint16_t port);
|
|||
rt_err_t rt_usbh_event_signal(struct uhost_msg* msg);
|
||||
|
||||
/* usb host controller driver interface */
|
||||
rt_inline rt_err_t rt_usb_hcd_alloc_pipe(uhcd_t hcd, upipe_t* pipe,
|
||||
struct uintf* intf, uep_desc_t ep, func_callback callback)
|
||||
rt_inline rt_err_t rt_usb_hcd_alloc_pipe(uhcd_t hcd, upipe_t pipe, uep_desc_t ep)
|
||||
{
|
||||
if(intf == RT_NULL) return -RT_EIO;
|
||||
|
||||
return hcd->ops->alloc_pipe(pipe, intf, ep, callback);
|
||||
return hcd->ops->alloc_pipe(pipe, ep);
|
||||
}
|
||||
|
||||
rt_inline rt_err_t rt_usb_hcd_free_pipe(uhcd_t hcd, upipe_t pipe)
|
||||
{
|
||||
RT_ASSERT(pipe != RT_NULL);
|
||||
|
||||
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)
|
||||
rt_inline int rt_usb_hcd_pipe_xfer(uhcd_t hcd, upipe_t pipe, void* buffer, int nbytes, int timeout)
|
||||
{
|
||||
if(pipe == RT_NULL) return -1;
|
||||
if(pipe->intf == RT_NULL) return -1;
|
||||
if(pipe->intf->device == RT_NULL) return -1;
|
||||
if(pipe->intf->device->status == DEV_STATUS_IDLE)
|
||||
return -1;
|
||||
|
||||
return hcd->ops->bulk_xfer(pipe, buffer, nbytes, timeout);
|
||||
return hcd->ops->pipe_xfer(pipe, USBH_PID_DATA, buffer, nbytes, timeout);
|
||||
}
|
||||
|
||||
rt_inline int rt_usb_hcd_control_xfer(uhcd_t hcd, struct uinstance* device, ureq_t setup,
|
||||
void* buffer, int nbytes, int timeout)
|
||||
rt_inline int rt_usb_hcd_setup_xfer(uhcd_t hcd, upipe_t pipe, ureq_t setup, int timeout)
|
||||
{
|
||||
if(device->status == DEV_STATUS_IDLE) return -1;
|
||||
|
||||
return hcd->ops->ctl_xfer(device, 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->intf == RT_NULL) return -1;
|
||||
if(pipe->intf->device == RT_NULL) return -1;
|
||||
if(pipe->intf->device->status == DEV_STATUS_IDLE)
|
||||
return -1;
|
||||
|
||||
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)
|
||||
{
|
||||
return hcd->ops->hub_ctrl(port, cmd, args);
|
||||
return hcd->ops->pipe_xfer(pipe, USBH_PID_SETUP, (void *)setup, 8, timeout);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -29,6 +29,6 @@ if GetDepend('RT_USBH_HID_KEYBOARD'):
|
|||
CPPPATH = [cwd, cwd + '/class', cwd + '/core', \
|
||||
cwd + '/include', cwd + '../../../include']
|
||||
|
||||
group = DefineGroup('rt_usbh', src, depend = ['RT_USING_USBH'], CPPPATH = CPPPATH)
|
||||
group = DefineGroup('rt_usbh', src, depend = ['RT_USING_USB_HOST'], CPPPATH = CPPPATH)
|
||||
|
||||
Return('group')
|
||||
|
|
|
@ -40,8 +40,7 @@ static struct uclass_driver hub_driver;
|
|||
*
|
||||
* @return the error code, RT_EOK on successfully.
|
||||
*/
|
||||
rt_err_t rt_usbh_hub_get_descriptor(struct uinstance* device, rt_uint8_t *buffer,
|
||||
rt_size_t nbytes)
|
||||
rt_err_t rt_usbh_hub_get_descriptor(struct uinstance* device, rt_uint8_t *buffer, rt_size_t nbytes)
|
||||
{
|
||||
struct urequest setup;
|
||||
int timeout = 100;
|
||||
|
@ -49,16 +48,20 @@ rt_err_t rt_usbh_hub_get_descriptor(struct uinstance* device, rt_uint8_t *buffer
|
|||
/* parameter check */
|
||||
RT_ASSERT(device != RT_NULL);
|
||||
|
||||
setup.request_type = USB_REQ_TYPE_DIR_IN | USB_REQ_TYPE_CLASS |
|
||||
USB_REQ_TYPE_DEVICE;
|
||||
setup.request_type = USB_REQ_TYPE_DIR_IN | USB_REQ_TYPE_CLASS | USB_REQ_TYPE_DEVICE;
|
||||
setup.bRequest = USB_REQ_GET_DESCRIPTOR;
|
||||
setup.wIndex = 0;
|
||||
setup.wLength = nbytes;
|
||||
setup.wValue = USB_DESC_TYPE_HUB << 8;
|
||||
|
||||
if(rt_usb_hcd_control_xfer(device->hcd, device, &setup, buffer, nbytes,
|
||||
timeout) == nbytes) return RT_EOK;
|
||||
else return -RT_FALSE;
|
||||
if(rt_usb_hcd_setup_xfer(device->hcd, device->pipe_ep0_out, &setup, timeout) == 8)
|
||||
{
|
||||
if(rt_usb_hcd_pipe_xfer(device->hcd, device->pipe_ep0_in, buffer, nbytes, timeout) == nbytes)
|
||||
{
|
||||
return RT_EOK;
|
||||
}
|
||||
}
|
||||
return -RT_FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -70,25 +73,27 @@ rt_err_t rt_usbh_hub_get_descriptor(struct uinstance* device, rt_uint8_t *buffer
|
|||
*
|
||||
* @return the error code, RT_EOK on successfully.
|
||||
*/
|
||||
rt_err_t rt_usbh_hub_get_status(struct uinstance* device, rt_uint8_t* buffer)
|
||||
rt_err_t rt_usbh_hub_get_status(struct uinstance* device, rt_uint32_t* buffer)
|
||||
{
|
||||
struct urequest setup;
|
||||
int timeout = 100;
|
||||
int length = 4;
|
||||
|
||||
/* parameter check */
|
||||
RT_ASSERT(device != RT_NULL);
|
||||
|
||||
setup.request_type = USB_REQ_TYPE_DIR_IN | USB_REQ_TYPE_CLASS |
|
||||
USB_REQ_TYPE_DEVICE;
|
||||
setup.request_type = USB_REQ_TYPE_DIR_IN | USB_REQ_TYPE_CLASS | USB_REQ_TYPE_DEVICE;
|
||||
setup.bRequest = USB_REQ_GET_STATUS;
|
||||
setup.wIndex = 0;
|
||||
setup.wLength = length;
|
||||
setup.wLength = 4;
|
||||
setup.wValue = 0;
|
||||
|
||||
if(rt_usb_hcd_control_xfer(device->hcd, device, &setup, buffer, length,
|
||||
timeout) == length) return RT_EOK;
|
||||
else return -RT_FALSE;
|
||||
if(rt_usb_hcd_setup_xfer(device->hcd, device->pipe_ep0_out, &setup, timeout) == 8)
|
||||
{
|
||||
if(rt_usb_hcd_pipe_xfer(device->hcd, device->pipe_ep0_in, buffer, 4, timeout) == 4)
|
||||
{
|
||||
return RT_EOK;
|
||||
}
|
||||
}
|
||||
return -RT_FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -101,12 +106,10 @@ rt_err_t rt_usbh_hub_get_status(struct uinstance* device, rt_uint8_t* buffer)
|
|||
*
|
||||
* @return the error code, RT_EOK on successfully.
|
||||
*/
|
||||
rt_err_t rt_usbh_hub_get_port_status(uhub_t hub, rt_uint16_t port,
|
||||
rt_uint8_t* buffer)
|
||||
rt_err_t rt_usbh_hub_get_port_status(uhub_t hub, rt_uint16_t port, rt_uint32_t* buffer)
|
||||
{
|
||||
struct urequest setup;
|
||||
int timeout = 100;
|
||||
int length = 4;
|
||||
|
||||
/* parameter check */
|
||||
RT_ASSERT(hub != RT_NULL);
|
||||
|
@ -119,16 +122,20 @@ rt_err_t rt_usbh_hub_get_port_status(uhub_t hub, rt_uint16_t port,
|
|||
return RT_EOK;
|
||||
}
|
||||
|
||||
setup.request_type = USB_REQ_TYPE_DIR_IN | USB_REQ_TYPE_CLASS |
|
||||
USB_REQ_TYPE_OTHER;
|
||||
setup.request_type = USB_REQ_TYPE_DIR_IN | USB_REQ_TYPE_CLASS | USB_REQ_TYPE_OTHER;
|
||||
setup.bRequest = USB_REQ_GET_STATUS;
|
||||
setup.wIndex = port;
|
||||
setup.wLength = 4;
|
||||
setup.wValue = 0;
|
||||
|
||||
if(rt_usb_hcd_control_xfer(hub->hcd, hub->self, &setup, buffer,
|
||||
length, timeout) == timeout) return RT_EOK;
|
||||
else return -RT_FALSE;
|
||||
if(rt_usb_hcd_setup_xfer(hub->hcd, hub->self->pipe_ep0_out, &setup, timeout) == 8)
|
||||
{
|
||||
if(rt_usb_hcd_pipe_xfer(hub->hcd, hub->self->pipe_ep0_in, buffer, 4, timeout) == 4)
|
||||
{
|
||||
return RT_EOK;
|
||||
}
|
||||
}
|
||||
return -RT_FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -141,8 +148,7 @@ rt_err_t rt_usbh_hub_get_port_status(uhub_t hub, rt_uint16_t port,
|
|||
*
|
||||
* @return the error code, RT_EOK on successfully.
|
||||
*/
|
||||
rt_err_t rt_usbh_hub_clear_port_feature(uhub_t hub, rt_uint16_t port,
|
||||
rt_uint16_t feature)
|
||||
rt_err_t rt_usbh_hub_clear_port_feature(uhub_t hub, rt_uint16_t port, rt_uint16_t feature)
|
||||
{
|
||||
struct urequest setup;
|
||||
int timeout = 100;
|
||||
|
@ -165,9 +171,11 @@ rt_err_t rt_usbh_hub_clear_port_feature(uhub_t hub, rt_uint16_t port,
|
|||
setup.wLength = 0;
|
||||
setup.wValue = feature;
|
||||
|
||||
if(rt_usb_hcd_control_xfer(hub->hcd, hub->self, &setup, RT_NULL, 0,
|
||||
timeout) == 0) return RT_EOK;
|
||||
else return -RT_FALSE;
|
||||
if(rt_usb_hcd_setup_xfer(hub->hcd, hub->self->pipe_ep0_out, &setup, timeout) == 8)
|
||||
{
|
||||
return RT_EOK;
|
||||
}
|
||||
return -RT_FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -204,8 +212,10 @@ rt_err_t rt_usbh_hub_set_port_feature(uhub_t hub, rt_uint16_t port,
|
|||
setup.wLength = 0;
|
||||
setup.wValue = feature;
|
||||
|
||||
if(rt_usb_hcd_control_xfer(hub->hcd, hub->self, &setup, RT_NULL, 0,
|
||||
timeout) == 0) return RT_EOK;
|
||||
if(rt_usb_hcd_setup_xfer(hub->hcd, hub->self->pipe_ep0_out, &setup, timeout) == 8)
|
||||
{
|
||||
return RT_EOK;
|
||||
}
|
||||
else return -RT_FALSE;
|
||||
}
|
||||
|
||||
|
@ -341,7 +351,7 @@ static rt_err_t rt_usbh_hub_port_change(uhub_t hub)
|
|||
|
||||
/* set usb device speed */
|
||||
device->speed = (pstatus & PORT_LSDA) ? 1 : 0;
|
||||
device->parent = hub;
|
||||
device->parent_hub = hub;
|
||||
device->hcd = hub->hcd;
|
||||
hub->child[i] = device;
|
||||
|
||||
|
@ -366,7 +376,7 @@ static rt_err_t rt_usbh_hub_port_change(uhub_t hub)
|
|||
static void rt_usbh_hub_irq(void* context)
|
||||
{
|
||||
upipe_t pipe;
|
||||
struct uintf* intf;
|
||||
struct uhintf* intf;
|
||||
uhub_t hub;
|
||||
int timeout = 100;
|
||||
|
||||
|
@ -389,8 +399,7 @@ static void rt_usbh_hub_irq(void* context)
|
|||
/* parameter check */
|
||||
RT_ASSERT(pipe->intf->device->hcd != RT_NULL);
|
||||
|
||||
rt_usb_hcd_int_xfer(intf->device->hcd, pipe, hub->buffer,
|
||||
pipe->ep.wMaxPacketSize, timeout);
|
||||
rt_usb_hcd_pipe_xfer(intf->device->hcd, pipe, hub->buffer, pipe->ep.wMaxPacketSize, timeout);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -408,7 +417,7 @@ static rt_err_t rt_usbh_hub_enable(void *arg)
|
|||
uep_desc_t ep_desc;
|
||||
uhub_t hub;
|
||||
struct uinstance* device;
|
||||
struct uintf* intf = (struct uintf*)arg;
|
||||
struct uhintf* intf = (struct uhintf*)arg;
|
||||
int timeout = 300;
|
||||
|
||||
/* paremeter check */
|
||||
|
|
|
@ -40,9 +40,6 @@ rt_err_t rt_usb_host_init(void)
|
|||
{
|
||||
ucd_t drv;
|
||||
rt_device_t uhc;
|
||||
#ifdef RT_USBH_HID
|
||||
uprotocal_t protocal;
|
||||
#endif
|
||||
|
||||
uhc = rt_device_find(USB_HOST_CONTROLLER_NAME);
|
||||
if(uhc == RT_NULL)
|
||||
|
@ -63,30 +60,6 @@ rt_err_t rt_usb_host_init(void)
|
|||
rt_usbh_class_driver_register(drv);
|
||||
#endif
|
||||
|
||||
#ifdef RT_USBH_HID
|
||||
/* register hid class driver */
|
||||
drv = rt_usbh_class_driver_hid();
|
||||
rt_usbh_class_driver_register(drv);
|
||||
|
||||
#ifdef RT_USBH_HID_KEYBOARD
|
||||
/* register hid keyboard protocal */
|
||||
protocal = rt_usbh_hid_protocal_kbd();
|
||||
rt_usbh_hid_protocal_register(protocal);
|
||||
#endif
|
||||
|
||||
#ifdef RT_USBH_HID_MOUSE
|
||||
/* register hid mouse protocal */
|
||||
protocal = rt_usbh_hid_protocal_mouse();
|
||||
rt_usbh_hid_protocal_register(protocal);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef RT_USBH_ADK
|
||||
/* register adk class driver */
|
||||
drv = rt_usbh_class_driver_adk();
|
||||
rt_usbh_class_driver_register(drv);
|
||||
#endif
|
||||
|
||||
/* register hub class driver */
|
||||
drv = rt_usbh_class_driver_hub();
|
||||
rt_usbh_class_driver_register(drv);
|
||||
|
|
Loading…
Reference in New Issue