Merge pull request #4376 from LeeChunHei/hid_fix

修復usb host hid和umouse驅動
This commit is contained in:
Bernard Xiong 2021-03-03 13:54:54 +08:00 committed by GitHub
commit 7628f36f05
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 109 additions and 67 deletions

View File

@ -642,6 +642,14 @@ menu "Using USB"
string "Udisk mount dir" string "Udisk mount dir"
default "/" default "/"
endif endif
config RT_USBH_HID
bool "Enable HID Drivers"
default n
if RT_USBH_HID
config RT_USBH_HID_MOUSE
bool "Enable HID mouse protocol"
default n
endif
endif endif
config RT_USING_USB_DEVICE config RT_USING_USB_DEVICE
bool "Using USB device" bool "Using USB device"

View File

@ -6,6 +6,7 @@
* Change Logs: * Change Logs:
* Date Author Notes * Date Author Notes
* 2011-12-12 Yi Qiu first version * 2011-12-12 Yi Qiu first version
* 2021-02-23 Leslie Lee update with current usb api
*/ */
#include <rtthread.h> #include <rtthread.h>
@ -26,7 +27,7 @@ static rt_list_t _protocal_list;
* *
* @return the error code, RT_EOK on successfully. * @return the error code, RT_EOK on successfully.
*/ */
rt_err_t rt_usbh_hid_set_idle(struct uintf* intf, int duration, int report_id) rt_err_t rt_usbh_hid_set_idle(struct uhintf* intf, int duration, int report_id)
{ {
struct urequest setup; struct urequest setup;
struct uinstance* device; struct uinstance* device;
@ -40,14 +41,15 @@ rt_err_t rt_usbh_hid_set_idle(struct uintf* intf, int duration, int report_id)
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_INTERFACE; USB_REQ_TYPE_INTERFACE;
setup.request = USB_REQ_SET_IDLE; setup.bRequest = USB_REQ_SET_IDLE;
setup.index = 0; setup.wIndex = 0;
setup.length = 0; setup.wLength = 0;
setup.value = (duration << 8 )| report_id; setup.wValue = (duration << 8 )| report_id;
if(rt_usb_hcd_control_xfer(device->hcd, device, &setup, RT_NULL, 0, if (rt_usb_hcd_setup_xfer(device->hcd, device->pipe_ep0_out, &setup, timeout) == 8)
timeout) == 0) return RT_EOK; return RT_EOK;
else return -RT_FALSE; else
return -RT_FALSE;
} }
/** /**
@ -59,7 +61,7 @@ rt_err_t rt_usbh_hid_set_idle(struct uintf* intf, int duration, int report_id)
* *
* @return the error code, RT_EOK on successfully. * @return the error code, RT_EOK on successfully.
*/ */
rt_err_t rt_usbh_hid_get_report(struct uintf* intf, rt_uint8_t type, rt_err_t rt_usbh_hid_get_report(struct uhintf* intf, rt_uint8_t type,
rt_uint8_t id, rt_uint8_t *buffer, rt_size_t size) rt_uint8_t id, rt_uint8_t *buffer, rt_size_t size)
{ {
struct urequest setup; struct urequest setup;
@ -74,14 +76,24 @@ rt_err_t rt_usbh_hid_get_report(struct uintf* intf, rt_uint8_t type,
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_INTERFACE; USB_REQ_TYPE_INTERFACE;
setup.request = USB_REQ_GET_REPORT; setup.bRequest = USB_REQ_GET_REPORT;
setup.index = intf->intf_desc->bInterfaceNumber; setup.wIndex = intf->intf_desc->bInterfaceNumber;
setup.length = size; setup.wLength = size;
setup.value = (type << 8 ) + id; setup.wValue = (type << 8 ) + id;
if(rt_usb_hcd_control_xfer(device->hcd, device, &setup, buffer, size, if (rt_usb_hcd_setup_xfer(device->hcd, device->pipe_ep0_out, &setup, timeout) == 8)
timeout) == size) return RT_EOK; {
else return -RT_FALSE; if (rt_usb_hcd_pipe_xfer(device->hcd, device->pipe_ep0_in, buffer, size, timeout) == size)
{
if (rt_usb_hcd_pipe_xfer(device->hcd, device->pipe_ep0_out, RT_NULL, 0, timeout) == 0)
{
return RT_EOK;
}
}
}
else
return -RT_FALSE;
return -RT_FALSE;
} }
/** /**
@ -93,7 +105,7 @@ rt_err_t rt_usbh_hid_get_report(struct uintf* intf, rt_uint8_t type,
* *
* @return the error code, RT_EOK on successfully. * @return the error code, RT_EOK on successfully.
*/ */
rt_err_t rt_usbh_hid_set_report(struct uintf* intf, rt_uint8_t *buffer, rt_size_t size) rt_err_t rt_usbh_hid_set_report(struct uhintf* intf, rt_uint8_t *buffer, rt_size_t size)
{ {
struct urequest setup; struct urequest setup;
struct uinstance* device; struct uinstance* device;
@ -107,14 +119,15 @@ rt_err_t rt_usbh_hid_set_report(struct uintf* intf, rt_uint8_t *buffer, rt_size_
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_INTERFACE; USB_REQ_TYPE_INTERFACE;
setup.request = USB_REQ_SET_REPORT; setup.bRequest = USB_REQ_SET_REPORT;
setup.index = intf->intf_desc->bInterfaceNumber; setup.wIndex = intf->intf_desc->bInterfaceNumber;
setup.length = size; setup.wLength = size;
setup.value = 0x02 << 8; setup.wValue = 0x02 << 8;
if(rt_usb_hcd_control_xfer(device->hcd, device, &setup, buffer, size, if (rt_usb_hcd_setup_xfer(device->hcd, device->pipe_ep0_out, &setup, timeout) == 8)
timeout) == size) return RT_EOK; return RT_EOK;
else return -RT_FALSE; else
return -RT_FALSE;
} }
/** /**
@ -125,7 +138,7 @@ rt_err_t rt_usbh_hid_set_report(struct uintf* intf, rt_uint8_t *buffer, rt_size_
* *
* @return the error code, RT_EOK on successfully. * @return the error code, RT_EOK on successfully.
*/ */
rt_err_t rt_usbh_hid_set_protocal(struct uintf* intf, int protocol) rt_err_t rt_usbh_hid_set_protocal(struct uhintf* intf, int protocol)
{ {
struct urequest setup; struct urequest setup;
struct uinstance* device; struct uinstance* device;
@ -139,14 +152,15 @@ rt_err_t rt_usbh_hid_set_protocal(struct uintf* intf, int protocol)
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_INTERFACE; USB_REQ_TYPE_INTERFACE;
setup.request = USB_REQ_SET_PROTOCOL; setup.bRequest = USB_REQ_SET_PROTOCOL;
setup.index = 0; setup.wIndex = 0;
setup.length = 0; setup.wLength = 0;
setup.value = protocol; setup.wValue = protocol;
if(rt_usb_hcd_control_xfer(device->hcd, device, &setup, RT_NULL, 0, if (rt_usb_hcd_setup_xfer(device->hcd, device->pipe_ep0_out, &setup, timeout) == 8)
timeout) == 0) return RT_EOK; return RT_EOK;
else return -RT_FALSE; else
return -RT_FALSE;
} }
/** /**
@ -159,7 +173,7 @@ rt_err_t rt_usbh_hid_set_protocal(struct uintf* intf, int protocol)
* *
* @return the error code, RT_EOK on successfully. * @return the error code, RT_EOK on successfully.
*/ */
rt_err_t rt_usbh_hid_get_report_descriptor(struct uintf* intf, rt_err_t rt_usbh_hid_get_report_descriptor(struct uhintf* intf,
rt_uint8_t *buffer, rt_size_t size) rt_uint8_t *buffer, rt_size_t size)
{ {
struct urequest setup; struct urequest setup;
@ -174,14 +188,24 @@ rt_err_t rt_usbh_hid_get_report_descriptor(struct uintf* intf,
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_INTERFACE; USB_REQ_TYPE_INTERFACE;
setup.request = USB_REQ_GET_DESCRIPTOR; setup.bRequest = USB_REQ_GET_DESCRIPTOR;
setup.index = 0; setup.wIndex = 0;
setup.length = size; setup.wLength = size;
setup.value = USB_DESC_TYPE_REPORT << 8; setup.wValue = USB_DESC_TYPE_REPORT << 8;
if(rt_usb_hcd_control_xfer(device->hcd, device, &setup, buffer, size, if (rt_usb_hcd_setup_xfer(device->hcd, device->pipe_ep0_out, &setup, timeout) == 8)
timeout) == size) return RT_EOK; {
else return -RT_FALSE; if (rt_usb_hcd_pipe_xfer(device->hcd, device->pipe_ep0_in, buffer, size, timeout) == size)
{
if (rt_usb_hcd_pipe_xfer(device->hcd, device->pipe_ep0_out, RT_NULL, 0, timeout) == 0)
{
return RT_EOK;
}
}
}
else
return -RT_FALSE;
return -RT_FALSE;
} }
/** /**
@ -220,16 +244,16 @@ static void rt_usbh_hid_callback(void* context)
RT_ASSERT(context != RT_NULL); RT_ASSERT(context != RT_NULL);
pipe = (upipe_t)context; pipe = (upipe_t)context;
hid = (struct uhid*)pipe->intf->user_data; hid = (struct uhid*)((struct uhintf*)pipe->inst)->user_data;
/* invoke protocal callback function */ /* invoke protocal callback function */
hid->protocal->callback((void*)hid); hid->protocal->callback((void*)hid);
/* parameter check */ /* parameter check */
RT_ASSERT(pipe->intf->device->hcd != RT_NULL); RT_ASSERT(((struct uhintf*)pipe->inst)->device->hcd != RT_NULL);
rt_usb_hcd_int_xfer(pipe->intf->device->hcd, pipe, hid->buffer, rt_usb_hcd_pipe_xfer(((struct uhintf*)pipe->inst)->device->hcd, pipe,
pipe->ep.wMaxPacketSize, timeout); hid->buffer, pipe->ep.wMaxPacketSize, timeout);
} }
/** /**
@ -268,9 +292,7 @@ static rt_err_t rt_usbh_hid_enable(void* arg)
int i = 0, pro_id; int i = 0, pro_id;
uprotocal_t protocal; uprotocal_t protocal;
struct uhid* hid; struct uhid* hid;
struct uintf* intf = (struct uintf*)arg; struct uhintf* intf = (struct uhintf*)arg;
int timeout = USB_TIMEOUT_BASIC;
upipe_t pipe;
/* parameter check */ /* parameter check */
if(intf == RT_NULL) if(intf == RT_NULL)
@ -319,19 +341,13 @@ static rt_err_t rt_usbh_hid_enable(void* arg)
if(!(ep_desc->bEndpointAddress & USB_DIR_IN)) continue; if(!(ep_desc->bEndpointAddress & USB_DIR_IN)) continue;
ret = rt_usb_hcd_alloc_pipe(intf->device->hcd, &hid->pipe_in, ret = rt_usb_hcd_alloc_pipe(intf->device->hcd, &hid->pipe_in,
intf, ep_desc, rt_usbh_hid_callback); intf, ep_desc);
if(ret != RT_EOK) return ret; if(ret != RT_EOK) return ret;
} }
/* initialize hid protocal */ /* initialize hid protocal */
hid->protocal->init((void*)intf); hid->protocal->init((void*)intf);
pipe = hid->pipe_in;
/* parameter check */
RT_ASSERT(pipe->intf->device->hcd != RT_NULL);
rt_usb_hcd_int_xfer(pipe->intf->device->hcd, hid->pipe_in,
hid->buffer, hid->pipe_in->ep.wMaxPacketSize, timeout);
return RT_EOK; return RT_EOK;
} }
@ -346,7 +362,7 @@ static rt_err_t rt_usbh_hid_enable(void* arg)
static rt_err_t rt_usbh_hid_disable(void* arg) static rt_err_t rt_usbh_hid_disable(void* arg)
{ {
struct uhid* hid; struct uhid* hid;
struct uintf* intf = (struct uintf*)arg; struct uhintf* intf = (struct uhintf*)arg;
RT_ASSERT(intf != RT_NULL); RT_ASSERT(intf != RT_NULL);
@ -364,9 +380,6 @@ static rt_err_t rt_usbh_hid_disable(void* arg)
/* free the hid instance */ /* free the hid instance */
rt_free(hid); rt_free(hid);
} }
/* free the instance */
rt_free(intf);
return RT_EOK; return RT_EOK;
} }

View File

@ -31,11 +31,11 @@ typedef struct uhid uhid_t;
#define USB_HID_KEYBOARD 1 #define USB_HID_KEYBOARD 1
#define USB_HID_MOUSE 2 #define USB_HID_MOUSE 2
rt_err_t rt_usbh_hid_set_idle(struct uintf* intf, int duration, int report_id); rt_err_t rt_usbh_hid_set_idle(struct uhintf* intf, int duration, int report_id);
rt_err_t rt_usbh_hid_get_report(struct uintf* intf, rt_uint8_t type, rt_uint8_t id, rt_uint8_t *buffer, rt_size_t size); rt_err_t rt_usbh_hid_get_report(struct uhintf* intf, rt_uint8_t type, rt_uint8_t id, rt_uint8_t *buffer, rt_size_t size);
rt_err_t rt_usbh_hid_set_report(struct uintf* intf, rt_uint8_t *buffer, rt_size_t size); rt_err_t rt_usbh_hid_set_report(struct uhintf* intf, rt_uint8_t *buffer, rt_size_t size);
rt_err_t rt_usbh_hid_set_protocal(struct uintf* intf, int protocol); rt_err_t rt_usbh_hid_set_protocal(struct uhintf* intf, int protocol);
rt_err_t rt_usbh_hid_get_report_descriptor(struct uintf* intf, rt_uint8_t *buffer, rt_size_t size); rt_err_t rt_usbh_hid_get_report_descriptor(struct uhintf* intf, rt_uint8_t *buffer, rt_size_t size);
rt_err_t rt_usbh_hid_protocal_register(uprotocal_t protocal); rt_err_t rt_usbh_hid_protocal_register(uprotocal_t protocal);
#endif #endif

View File

@ -126,15 +126,36 @@ static rt_err_t rt_usbh_hid_mouse_callback(void* arg)
return RT_EOK; return RT_EOK;
} }
rt_thread_t mouse_thread;
void mouse_task(void* param)
{
struct uhintf* intf = (struct uhintf*)param;
while (1)
{
if (rt_usb_hcd_pipe_xfer(intf->device->hcd, ((struct uhid*)intf->user_data)->pipe_in,
((struct uhid*)intf->user_data)->buffer, ((struct uhid*)intf->user_data)->pipe_in->ep.wMaxPacketSize,
USB_TIMEOUT_BASIC) == 0)
{
break;
}
rt_usbh_hid_mouse_callback(intf->user_data);
}
}
static rt_err_t rt_usbh_hid_mouse_init(void* arg) static rt_err_t rt_usbh_hid_mouse_init(void* arg)
{ {
struct uintf* intf = (struct uintf*)arg; struct uhintf* intf = (struct uhintf*)arg;
RT_ASSERT(intf != RT_NULL); RT_ASSERT(intf != RT_NULL);
rt_usbh_hid_set_protocal(intf, 0); rt_usbh_hid_set_protocal(intf, 0);
rt_usbh_hid_set_idle(intf, 10, 0); rt_usbh_hid_set_idle(intf, 0, 0);
mouse_thread = rt_thread_create("mouse0", mouse_task, intf, 500, 8, 100);
rt_thread_startup(mouse_thread);
RT_DEBUG_LOG(RT_DEBUG_USB, ("start usb mouse\n")); RT_DEBUG_LOG(RT_DEBUG_USB, ("start usb mouse\n"));
#ifdef RT_USING_RTGUI #ifdef RT_USING_RTGUI