summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzhugengyu <[email protected]>2022-09-22 18:32:42 +0800
committersakumisu <[email protected]>2022-09-22 22:12:09 +0800
commitbec72e5d4c3e7359ba9e6787896b5421958bc852 (patch)
tree673768fcfff77f70b4993bf0af0902e9249a5610
parent590ffc8847c8871320379ed6c38b51f361ed6640 (diff)
xhci keyboard and mouse ok
-rw-r--r--class/hid/usb_hid.h10
-rw-r--r--class/hid/usbh_hid.c29
-rw-r--r--demo/phytium-e2000/usbhost/inc/usb_host.h2
-rw-r--r--demo/phytium-e2000/usbhost/src/cmd_usb.c2
-rw-r--r--demo/phytium-e2000/usbhost/src/usb_host.c50
-rw-r--r--demo/phytium-e2000/usbhost/src/usb_input.c313
-rw-r--r--port/xhci/usb_config.h1
-rw-r--r--port/xhci/usb_hc_xhci.c4
8 files changed, 354 insertions, 57 deletions
diff --git a/class/hid/usb_hid.h b/class/hid/usb_hid.h
index 9a36676f..19539e7f 100644
--- a/class/hid/usb_hid.h
+++ b/class/hid/usb_hid.h
@@ -191,6 +191,12 @@
#define HID_MOUSE_INPUT_REPORT_BUTTON3 (1 << 2)
#define HID_MOUSE_INPUT_REPORT_BUTTON_MASK (7)
+#define HID_MOUSE_INPUT_BUTTON_LEFT (1 << 0)
+#define HID_MOUSE_INPUT_BUTTON_RIGHT (1 << 1)
+#define HID_MOUSE_INPUT_BUTTON_MIDDLE (1 << 2)
+#define HID_MOUSE_INPUT_BUTTON_BACKWARD (1 << 3)
+#define HID_MOUSE_INPUT_BUTTON_FORWARD (1 << 4)
+
/* Joystick input report (4 bytes) (HID D.1) */
#define HID_JS_INPUT_REPORT_HATSWITCH_SHIFT (0)
#define HID_JS_INPUT_REPORT_HATSWITCH_MASK (15 << HID_JSIN_HATSWITCH_SHIFT)
@@ -546,7 +552,7 @@ struct usb_hid_descriptor {
/* Keyboard input report (8 bytes) (HID B.1) */
struct usb_hid_kbd_report
{
- uint8_t modifier; /* Modifier keys. See USBHID_MODIFIER_* definitions */
+ uint8_t modifier; /* Modifier keys. See HID_MODIFER_* definitions */
uint8_t reserved;
uint8_t key[6]; /* Keycode 1-6 */
};
@@ -558,7 +564,7 @@ struct usb_hid_kbd_report
/* Mouse input report (HID B.2) */
struct usb_hid_mouse_report
{
- uint8_t buttons; /* See USBHID_MOUSEIN_* definitions */
+ uint8_t buttons; /* See HID_MOUSE_INPUT_BUTTON_* definitions */
uint8_t xdisp; /* X displacement */
uint8_t ydisp; /* y displacement */
/* Device specific additional bytes may follow */
diff --git a/class/hid/usbh_hid.c b/class/hid/usbh_hid.c
index e844177b..99909e90 100644
--- a/class/hid/usbh_hid.c
+++ b/class/hid/usbh_hid.c
@@ -84,8 +84,14 @@ int usbh_hid_set_idle(struct usbh_hid *hid_class, uint8_t report_id, uint8_t dur
setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE;
setup->bRequest = HID_REQUEST_SET_IDLE;
- setup->wValue = report_id;
- setup->wIndex = (duration << 8) | hid_class->intf;
+ //setup->wValue = report_id;
+ //setup->wIndex = (duration << 8) | hid_class->intf;
+ /* wValue, high-bytes sets the duration, or the max amount of time between reports
+ 0x00 = hid will send a report only when report data has changed or duration time elapsed
+ low-bytes indicate the report id that the requeset applies to */
+ setup->wValue = (duration << 8) | report_id;
+ /* wIndex, num of interface that supports the request */
+ setup->wIndex = hid_class->intf;
setup->wLength = 0;
return usbh_control_transfer(hid_class->hport->ep0, setup, NULL);
@@ -110,6 +116,19 @@ int usbh_hid_get_idle(struct usbh_hid *hid_class, uint8_t *buffer)
return ret;
}
+int usbh_hid_set_protocol(struct usbh_hid *hid_class, uint8_t protocol)
+{
+ struct usb_setup_packet *setup = &hid_class->hport->setup;
+
+ setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE;
+ setup->bRequest = HID_REQUEST_SET_PROTOCOL;
+ setup->wValue = protocol;
+ setup->wIndex = 0;
+ setup->wLength = 0;
+
+ return usbh_control_transfer(hid_class->hport->ep0, setup, NULL);
+}
+
int usbh_hid_connect(struct usbh_hubport *hport, uint8_t intf)
{
struct usb_endpoint_descriptor *ep_desc;
@@ -128,6 +147,12 @@ int usbh_hid_connect(struct usbh_hubport *hport, uint8_t intf)
hport->config.intf[intf].priv = hid_class;
+ // /* 0x0 = boot protocol, 0x1 = report protocol */
+ // ret = usbh_hid_set_protocol(hid_class, 0x1);
+ // if (ret < 0) {
+ // return ret;
+ // }
+
ret = usbh_hid_set_idle(hid_class, 0, 0);
if (ret < 0) {
return ret;
diff --git a/demo/phytium-e2000/usbhost/inc/usb_host.h b/demo/phytium-e2000/usbhost/inc/usb_host.h
index 11aaab8e..223910f1 100644
--- a/demo/phytium-e2000/usbhost/inc/usb_host.h
+++ b/demo/phytium-e2000/usbhost/inc/usb_host.h
@@ -41,7 +41,7 @@ extern "C"
/*****************************************************************************/
BaseType_t FFreeRTOSInitUsb(void);
BaseType_t FFreeRTOSWriteReadUsbDisk(void);
-BaseType_t FFreeRTOSRecvHidInput(void);
+BaseType_t FFreeRTOSRecvInput(void);
#ifdef __cplusplus
}
diff --git a/demo/phytium-e2000/usbhost/src/cmd_usb.c b/demo/phytium-e2000/usbhost/src/cmd_usb.c
index a6c8465c..4416fb4c 100644
--- a/demo/phytium-e2000/usbhost/src/cmd_usb.c
+++ b/demo/phytium-e2000/usbhost/src/cmd_usb.c
@@ -47,7 +47,7 @@ static int USBCmdEntry(int argc, char *argv[])
}
else if (!strcmp(argv[1], "hid"))
{
- ret = FFreeRTOSRecvHidInput();
+ ret = FFreeRTOSRecvInput();
}
return ret;
diff --git a/demo/phytium-e2000/usbhost/src/usb_host.c b/demo/phytium-e2000/usbhost/src/usb_host.c
index 69367c0c..f78eb04f 100644
--- a/demo/phytium-e2000/usbhost/src/usb_host.c
+++ b/demo/phytium-e2000/usbhost/src/usb_host.c
@@ -184,38 +184,6 @@ err_exit:
vTaskDelete(NULL);
}
-static void UsbHidTask(void * args)
-{
- int ret;
- struct usbh_hid *hid_class;
- static uint8_t hid_buffer[128] = {0};
-
- while (TRUE)
- {
- hid_class = (struct usbh_hid *)usbh_find_class_instance("/dev/input0");
- if (hid_class == NULL)
- {
- USB_LOG_RAW("do not find /dev/input0\r\n");
- goto err_exit;
- }
-
- ret = usbh_int_transfer(hid_class->intin, hid_buffer, 8, 1000);
- if (ret < 0)
- {
- USB_LOG_RAW("intr in error,ret:%d\r\n", ret);
- goto err_exit;
- }
- USB_LOG_RAW("recv len:%d, key:[0x%x, 0x%x, 0x%x, 0x%x]\r\n",
- ret,
- hid_buffer[0], hid_buffer[1], hid_buffer[2], hid_buffer[3]);
-
- vTaskDelay(10);
- }
-
-err_exit:
- vTaskDelete(NULL);
-}
-
BaseType_t FFreeRTOSInitUsb(void)
{
BaseType_t ret = pdPASS;
@@ -254,21 +222,3 @@ BaseType_t FFreeRTOSWriteReadUsbDisk(void)
return ret;
}
-BaseType_t FFreeRTOSRecvHidInput(void)
-{
- BaseType_t ret = pdPASS;
-
- taskENTER_CRITICAL(); /* no schedule when create task */
-
- ret = xTaskCreate((TaskFunction_t )UsbHidTask,
- (const char* )"UsbHidTask",
- (uint16_t )2048,
- NULL,
- (UBaseType_t )configMAX_PRIORITIES - 1,
- NULL);
- FASSERT_MSG(pdPASS == ret, "create task failed");
-
- taskEXIT_CRITICAL(); /* allow schedule since task created */
-
- return ret;
-} \ No newline at end of file
diff --git a/demo/phytium-e2000/usbhost/src/usb_input.c b/demo/phytium-e2000/usbhost/src/usb_input.c
new file mode 100644
index 00000000..28ae26b6
--- /dev/null
+++ b/demo/phytium-e2000/usbhost/src/usb_input.c
@@ -0,0 +1,313 @@
+/*
+ * Copyright : (C) 2022 Phytium Information Technology, Inc.
+ * All Rights Reserved.
+ *
+ * This program is OPEN SOURCE software: you can redistribute it and/or modify it
+ * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd,
+ * either version 1.0 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the Phytium Public License for more details.
+ *
+ *
+ * FilePath: usb_input.c
+ * Date: 2022-07-22 13:57:42
+ * LastEditTime: 2022-07-22 13:57:43
+ * Description:  This files is for
+ *
+ * Modify History:
+ * Ver   Who        Date         Changes
+ * ----- ------     --------    --------------------------------------
+ * 1.0 zhugengyu 2022/9/20 init commit
+ */
+/***************************** Include Files *********************************/
+#include <stdio.h>
+#include <string.h>
+
+#include "FreeRTOS.h"
+#include "task.h"
+
+#include "ft_assert.h"
+#include "interrupt.h"
+#include "cpu_info.h"
+#include "ft_debug.h"
+
+#include "usbh_core.h"
+#include "usbh_hid.h"
+/************************** Constant Definitions *****************************/
+#define HID_KEYCODE_TO_ASCII \
+ {0 , 0 }, /* 0x00 */ \
+ {0 , 0 }, /* 0x01 */ \
+ {0 , 0 }, /* 0x02 */ \
+ {0 , 0 }, /* 0x03 */ \
+ {'a' , 'A' }, /* 0x04 */ \
+ {'b' , 'B' }, /* 0x05 */ \
+ {'c' , 'C' }, /* 0x06 */ \
+ {'d' , 'D' }, /* 0x07 */ \
+ {'e' , 'E' }, /* 0x08 */ \
+ {'f' , 'F' }, /* 0x09 */ \
+ {'g' , 'G' }, /* 0x0a */ \
+ {'h' , 'H' }, /* 0x0b */ \
+ {'i' , 'I' }, /* 0x0c */ \
+ {'j' , 'J' }, /* 0x0d */ \
+ {'k' , 'K' }, /* 0x0e */ \
+ {'l' , 'L' }, /* 0x0f */ \
+ {'m' , 'M' }, /* 0x10 */ \
+ {'n' , 'N' }, /* 0x11 */ \
+ {'o' , 'O' }, /* 0x12 */ \
+ {'p' , 'P' }, /* 0x13 */ \
+ {'q' , 'Q' }, /* 0x14 */ \
+ {'r' , 'R' }, /* 0x15 */ \
+ {'s' , 'S' }, /* 0x16 */ \
+ {'t' , 'T' }, /* 0x17 */ \
+ {'u' , 'U' }, /* 0x18 */ \
+ {'v' , 'V' }, /* 0x19 */ \
+ {'w' , 'W' }, /* 0x1a */ \
+ {'x' , 'X' }, /* 0x1b */ \
+ {'y' , 'Y' }, /* 0x1c */ \
+ {'z' , 'Z' }, /* 0x1d */ \
+ {'1' , '!' }, /* 0x1e */ \
+ {'2' , '@' }, /* 0x1f */ \
+ {'3' , '#' }, /* 0x20 */ \
+ {'4' , '$' }, /* 0x21 */ \
+ {'5' , '%' }, /* 0x22 */ \
+ {'6' , '^' }, /* 0x23 */ \
+ {'7' , '&' }, /* 0x24 */ \
+ {'8' , '*' }, /* 0x25 */ \
+ {'9' , '(' }, /* 0x26 */ \
+ {'0' , ')' }, /* 0x27 */ \
+ {'\r' , '\r' }, /* 0x28 */ \
+ {'\x1b', '\x1b' }, /* 0x29 */ \
+ {'\b' , '\b' }, /* 0x2a */ \
+ {'\t' , '\t' }, /* 0x2b */ \
+ {' ' , ' ' }, /* 0x2c */ \
+ {'-' , '_' }, /* 0x2d */ \
+ {'=' , '+' }, /* 0x2e */ \
+ {'[' , '{' }, /* 0x2f */ \
+ {']' , '}' }, /* 0x30 */ \
+ {'\\' , '|' }, /* 0x31 */ \
+ {'#' , '~' }, /* 0x32 */ \
+ {';' , ':' }, /* 0x33 */ \
+ {'\'' , '\"' }, /* 0x34 */ \
+ {'`' , '~' }, /* 0x35 */ \
+ {',' , '<' }, /* 0x36 */ \
+ {'.' , '>' }, /* 0x37 */ \
+ {'/' , '?' }, /* 0x38 */ \
+ \
+ {0 , 0 }, /* 0x39 */ \
+ {0 , 0 }, /* 0x3a */ \
+ {0 , 0 }, /* 0x3b */ \
+ {0 , 0 }, /* 0x3c */ \
+ {0 , 0 }, /* 0x3d */ \
+ {0 , 0 }, /* 0x3e */ \
+ {0 , 0 }, /* 0x3f */ \
+ {0 , 0 }, /* 0x40 */ \
+ {0 , 0 }, /* 0x41 */ \
+ {0 , 0 }, /* 0x42 */ \
+ {0 , 0 }, /* 0x43 */ \
+ {0 , 0 }, /* 0x44 */ \
+ {0 , 0 }, /* 0x45 */ \
+ {0 , 0 }, /* 0x46 */ \
+ {0 , 0 }, /* 0x47 */ \
+ {0 , 0 }, /* 0x48 */ \
+ {0 , 0 }, /* 0x49 */ \
+ {0 , 0 }, /* 0x4a */ \
+ {0 , 0 }, /* 0x4b */ \
+ {0 , 0 }, /* 0x4c */ \
+ {0 , 0 }, /* 0x4d */ \
+ {0 , 0 }, /* 0x4e */ \
+ {0 , 0 }, /* 0x4f */ \
+ {0 , 0 }, /* 0x50 */ \
+ {0 , 0 }, /* 0x51 */ \
+ {0 , 0 }, /* 0x52 */ \
+ {0 , 0 }, /* 0x53 */ \
+ \
+ {'/' , '/' }, /* 0x54 */ \
+ {'*' , '*' }, /* 0x55 */ \
+ {'-' , '-' }, /* 0x56 */ \
+ {'+' , '+' }, /* 0x57 */ \
+ {'\r' , '\r' }, /* 0x58 */ \
+ {'1' , 0 }, /* 0x59 */ \
+ {'2' , 0 }, /* 0x5a */ \
+ {'3' , 0 }, /* 0x5b */ \
+ {'4' , 0 }, /* 0x5c */ \
+ {'5' , '5' }, /* 0x5d */ \
+ {'6' , 0 }, /* 0x5e */ \
+ {'7' , 0 }, /* 0x5f */ \
+ {'8' , 0 }, /* 0x60 */ \
+ {'9' , 0 }, /* 0x61 */ \
+ {'0' , 0 }, /* 0x62 */ \
+ {'0' , 0 }, /* 0x63 */ \
+ {'=' , '=' }, /* 0x67 */ \
+
+/**************************** Type Definitions *******************************/
+
+/************************** Variable Definitions *****************************/
+static u8 const keycode2ascii[128][2] = { HID_KEYCODE_TO_ASCII };
+
+/***************** Macros (Inline Functions) Definitions *********************/
+#define FUSB_DEBUG_TAG "USB-INPUT"
+#define FUSB_ERROR(format, ...) FT_DEBUG_PRINT_E(FUSB_DEBUG_TAG, format, ##__VA_ARGS__)
+#define FUSB_WARN(format, ...) FT_DEBUG_PRINT_W(FUSB_DEBUG_TAG, format, ##__VA_ARGS__)
+#define FUSB_INFO(format, ...) FT_DEBUG_PRINT_I(FUSB_DEBUG_TAG, format, ##__VA_ARGS__)
+#define FUSB_DEBUG(format, ...) FT_DEBUG_PRINT_D(FUSB_DEBUG_TAG, format, ##__VA_ARGS__)
+
+/************************** Function Prototypes ******************************/
+
+
+/*****************************************************************************/
+static inline void UsbMouseLeftButtonCB(void)
+{
+ printf(" Button Left\r\n");
+}
+
+static inline void UsbMouseRightButtonCB(void)
+{
+ printf(" Button Right\r\n");
+}
+
+static inline void UsbMouseMiddleButtonCB(void)
+{
+ printf(" Button Middle\r\n");
+}
+
+static void UsbMouseHandleInput(struct usb_hid_mouse_report *input)
+{
+ /*------------- button state -------------*/
+ if (input->buttons & HID_MOUSE_INPUT_BUTTON_LEFT)
+ {
+ UsbMouseLeftButtonCB();
+ }
+
+ if (input->buttons & HID_MOUSE_INPUT_BUTTON_MIDDLE)
+ {
+ UsbMouseMiddleButtonCB();
+ }
+
+ if (input->buttons & HID_MOUSE_INPUT_BUTTON_RIGHT)
+ {
+ UsbMouseRightButtonCB();
+ }
+
+ /*------------- cursor movement -------------*/
+ printf(" Cursor %d %d %d\r\n", input->xdisp, input->ydisp, input->wdisp);
+}
+
+/* look up new key in previous keys */
+static inline boolean FindKeyInPrevInput(const struct usb_hid_kbd_report *report, u8 keycode)
+{
+ for(u8 i=0; i < 6; i++)
+ {
+ if (report->key[i] == keycode)
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static void UsbKeyBoardHandleInput(struct usb_hid_kbd_report *input)
+{
+ static struct usb_hid_kbd_report prev_input = { 0, 0, {0} }; /* previous report to check key released */
+
+ /* ------------- example code ignore control (non-printable) key affects ------------- */
+ for (u8 i = 0; i < 6; i++)
+ {
+ if (input->key[i])
+ {
+ if (FindKeyInPrevInput(&prev_input, input->key[i]))
+ {
+ /* exist in previous report means the current key is holding */
+ }
+ else
+ {
+ /* not existed in previous report means the current key is pressed */
+ boolean is_shift = input->modifier & (HID_MODIFER_LSHIFT | HID_MODIFER_RSHIFT);
+ u8 ch = keycode2ascii[input->key[i]][is_shift ? 1 : 0];
+ putchar(ch);
+ if ('\r' == ch)
+ {
+ putchar('\n');
+ }
+
+ fflush(stdout); /* flush right away, else libc will wait for newline */
+ }
+ }
+ }
+
+ prev_input = *input;
+}
+
+static u8 UsbInputGetInterfaceProtocol(struct usbh_hid *hid_class)
+{
+ struct usbh_hubport *hport = hid_class->hport;
+ u8 intf = hid_class->intf;
+ const struct usb_interface_descriptor *intf_desc = &hport->config.intf->altsetting[intf].intf_desc;
+
+ return intf_desc->bInterfaceProtocol;
+}
+
+static void UsbInputTask(void * args)
+{
+ int ret;
+ struct usbh_hid *hid_class;
+ static uint8_t hid_buffer[128] = {0};
+ u8 intf_protocol;
+
+ FUSB_INFO("%s", __func__);
+
+ while (TRUE)
+ {
+ hid_class = (struct usbh_hid *)usbh_find_class_instance("/dev/input0");
+ if (hid_class == NULL)
+ {
+ USB_LOG_RAW("do not find /dev/input0\r\n");
+ goto err_exit;
+ }
+
+ ret = usbh_int_transfer(hid_class->intin, hid_buffer, 8, 1000);
+ if (ret < 0)
+ {
+ USB_LOG_RAW("intr in error,ret:%d\r\n", ret);
+ }
+
+ intf_protocol = UsbInputGetInterfaceProtocol(hid_class);
+ if (HID_PROTOCOL_KEYBOARD == intf_protocol)
+ {
+ UsbKeyBoardHandleInput((struct usb_hid_kbd_report *)hid_buffer);
+ }
+ else if (HID_PROTOCOL_MOUSE == intf_protocol)
+ {
+ UsbMouseHandleInput((struct usb_hid_mouse_report *)hid_buffer);
+ }
+ else
+ {
+ FUSB_ERROR("unsupported hid interface %d", intf_protocol);
+ goto err_exit;
+ }
+
+ vTaskDelay(10);
+ }
+
+err_exit:
+ vTaskDelete(NULL);
+}
+
+BaseType_t FFreeRTOSRecvInput(void)
+{
+ BaseType_t ret = pdPASS;
+
+ taskENTER_CRITICAL(); /* no schedule when create task */
+
+ ret = xTaskCreate((TaskFunction_t )UsbInputTask,
+ (const char* )"UsbInputTask",
+ (uint16_t )2048,
+ NULL,
+ (UBaseType_t )configMAX_PRIORITIES - 1,
+ NULL);
+ FASSERT_MSG(pdPASS == ret, "create task failed");
+
+ taskEXIT_CRITICAL(); /* allow schedule since task created */
+
+ return ret;
+} \ No newline at end of file
diff --git a/port/xhci/usb_config.h b/port/xhci/usb_config.h
index 29954dfc..743ab283 100644
--- a/port/xhci/usb_config.h
+++ b/port/xhci/usb_config.h
@@ -72,6 +72,7 @@
// #define CONFIG_USBHOST_GET_STRING_DESC
// #define CONFIG_USBDEV_MSC_THREAD
+#define CONFIG_INPUT_MOUSE_WHEEL
#ifdef CONFIG_USBDEV_MSC_THREAD
#ifndef CONFIG_USBDEV_MSC_STACKSIZE
diff --git a/port/xhci/usb_hc_xhci.c b/port/xhci/usb_hc_xhci.c
index da07da8d..d709a6b1 100644
--- a/port/xhci/usb_hc_xhci.c
+++ b/port/xhci/usb_hc_xhci.c
@@ -1092,7 +1092,9 @@ int usbh_submit_urb(struct usbh_urb *urb)
/* wait all ring handled by xHc */
int cc = xhci_event_wait(xhci, ppipe, &ppipe->reqs);
- if (cc != CC_SUCCESS) {
+ if ((cc != CC_SUCCESS) &&
+ !((cc == CC_TIMEOUT) && (ppipe->eptype == USB_ENDPOINT_TYPE_INTERRUPT))) {
+ /* ignore transfer timeout for interrupt type */
USB_LOG_ERR("%s: xfer failed (cc %d)\n", __func__, cc);
ret = -1;
urb->errorcode = cc;