usb: hid: boot protocol
Set_Protocol and Get_Protocol requests are handled now. Tested with USB3CV. Signed-off-by: Marcin Szymczyk <Marcin.Szymczyk@nordicsemi.no>
This commit is contained in:
parent
4446b16e24
commit
801b54edb9
5 changed files with 82 additions and 4 deletions
|
@ -60,6 +60,7 @@ struct usb_hid_descriptor {
|
||||||
typedef int (*hid_cb_t)(struct usb_setup_packet *setup, s32_t *len,
|
typedef int (*hid_cb_t)(struct usb_setup_packet *setup, s32_t *len,
|
||||||
u8_t **data);
|
u8_t **data);
|
||||||
typedef void (*hid_int_ready_callback)(void);
|
typedef void (*hid_int_ready_callback)(void);
|
||||||
|
typedef void (*hid_protocol_cb_t)(u8_t protocol);
|
||||||
typedef void (*hid_idle_cb_t)(u16_t report_id);
|
typedef void (*hid_idle_cb_t)(u16_t report_id);
|
||||||
|
|
||||||
struct hid_ops {
|
struct hid_ops {
|
||||||
|
@ -69,6 +70,7 @@ struct hid_ops {
|
||||||
hid_cb_t set_report;
|
hid_cb_t set_report;
|
||||||
hid_cb_t set_idle;
|
hid_cb_t set_idle;
|
||||||
hid_cb_t set_protocol;
|
hid_cb_t set_protocol;
|
||||||
|
hid_protocol_cb_t protocol_change;
|
||||||
hid_idle_cb_t on_idle;
|
hid_idle_cb_t on_idle;
|
||||||
/*
|
/*
|
||||||
* int_in_ready is an optional callback that is called when
|
* int_in_ready is an optional callback that is called when
|
||||||
|
@ -162,6 +164,10 @@ struct hid_ops {
|
||||||
#define COLLECTION_PHYSICAL 0x00
|
#define COLLECTION_PHYSICAL 0x00
|
||||||
#define COLLECTION_APPLICATION 0x01
|
#define COLLECTION_APPLICATION 0x01
|
||||||
|
|
||||||
|
/* Protocols */
|
||||||
|
#define HID_PROTOCOL_BOOT 0x00
|
||||||
|
#define HID_PROTOCOL_REPORT 0x01
|
||||||
|
|
||||||
/* Register HID device */
|
/* Register HID device */
|
||||||
void usb_hid_register_device(const u8_t *desc, size_t size,
|
void usb_hid_register_device(const u8_t *desc, size_t size,
|
||||||
const struct hid_ops *op);
|
const struct hid_ops *op);
|
||||||
|
|
|
@ -2,6 +2,7 @@ CONFIG_USB=y
|
||||||
CONFIG_USB_DEVICE_STACK=y
|
CONFIG_USB_DEVICE_STACK=y
|
||||||
CONFIG_USB_DEVICE_HID=y
|
CONFIG_USB_DEVICE_HID=y
|
||||||
CONFIG_USB_DEVICE_PRODUCT="Zephyr HID sample"
|
CONFIG_USB_DEVICE_PRODUCT="Zephyr HID sample"
|
||||||
|
CONFIG_USB_HID_BOOT_PROTOCOL=y
|
||||||
|
|
||||||
CONFIG_LOG=y
|
CONFIG_LOG=y
|
||||||
CONFIG_USB_DRIVER_LOG_LEVEL_ERR=y
|
CONFIG_USB_DRIVER_LOG_LEVEL_ERR=y
|
||||||
|
|
|
@ -99,10 +99,17 @@ static void idle_cb(u16_t report_id)
|
||||||
LOG_DBG("Idle callback: wrote %d bytes with ret %d", wrote, ret);
|
LOG_DBG("Idle callback: wrote %d bytes with ret %d", wrote, ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void protocol_cb(u8_t protocol)
|
||||||
|
{
|
||||||
|
LOG_DBG("New protocol: %s", protocol == HID_PROTOCOL_BOOT ?
|
||||||
|
"boot" : "report");
|
||||||
|
}
|
||||||
|
|
||||||
static const struct hid_ops ops = {
|
static const struct hid_ops ops = {
|
||||||
.int_in_ready = in_ready_cb,
|
.int_in_ready = in_ready_cb,
|
||||||
.status_cb = status_cb,
|
.status_cb = status_cb,
|
||||||
.on_idle = idle_cb,
|
.on_idle = idle_cb,
|
||||||
|
.protocol_change = protocol_cb,
|
||||||
};
|
};
|
||||||
|
|
||||||
void main(void)
|
void main(void)
|
||||||
|
|
|
@ -45,4 +45,29 @@ config USB_HID_REPORTS
|
||||||
Number of HID reports in the instance.
|
Number of HID reports in the instance.
|
||||||
Must be equal or higher than highest report ID (if they are not consecutive).
|
Must be equal or higher than highest report ID (if they are not consecutive).
|
||||||
|
|
||||||
|
config USB_HID_BOOT_PROTOCOL
|
||||||
|
bool
|
||||||
|
prompt "Enable USB HID Boot Protocol handling"
|
||||||
|
help
|
||||||
|
Sets bInterfaceSubClass to 1 and enables Set_Protocol and Get_Protocol
|
||||||
|
requests handling.
|
||||||
|
See Chapter 4.2 of Device Class Definition for Human Interface Devices 1.11
|
||||||
|
for more information.
|
||||||
|
|
||||||
|
if USB_HID_BOOT_PROTOCOL
|
||||||
|
|
||||||
|
config USB_HID_PROTOCOL_CODE
|
||||||
|
int "HID protocol code"
|
||||||
|
default 0
|
||||||
|
range 0 2
|
||||||
|
help
|
||||||
|
Sets bIntefaceProtocol in HID instance.
|
||||||
|
0 = None
|
||||||
|
1 = Keyboard
|
||||||
|
2 = Mouse
|
||||||
|
See Chapter 4.3 of Device Class Definition for Human Interface Devices 1.11
|
||||||
|
for more information.
|
||||||
|
|
||||||
|
endif # USB_HID_BOOT_PROTOCOL
|
||||||
|
|
||||||
endif # USB_DEVICE_HID
|
endif # USB_DEVICE_HID
|
||||||
|
|
|
@ -44,8 +44,13 @@ USBD_CLASS_DESCR_DEFINE(primary) struct usb_hid_config hid_cfg = {
|
||||||
.bAlternateSetting = 0,
|
.bAlternateSetting = 0,
|
||||||
.bNumEndpoints = 1,
|
.bNumEndpoints = 1,
|
||||||
.bInterfaceClass = HID_CLASS,
|
.bInterfaceClass = HID_CLASS,
|
||||||
|
#ifdef CONFIG_USB_HID_BOOT_PROTOCOL
|
||||||
|
.bInterfaceSubClass = 1,
|
||||||
|
.bInterfaceProtocol = CONFIG_USB_HID_PROTOCOL_CODE,
|
||||||
|
#else
|
||||||
.bInterfaceSubClass = 0,
|
.bInterfaceSubClass = 0,
|
||||||
.bInterfaceProtocol = 0,
|
.bInterfaceProtocol = 0,
|
||||||
|
#endif
|
||||||
.iInterface = 0,
|
.iInterface = 0,
|
||||||
},
|
},
|
||||||
.if0_hid = {
|
.if0_hid = {
|
||||||
|
@ -95,6 +100,9 @@ static struct hid_device_info {
|
||||||
bool idle_id_report;
|
bool idle_id_report;
|
||||||
u8_t idle_rate[CONFIG_USB_HID_REPORTS + 1];
|
u8_t idle_rate[CONFIG_USB_HID_REPORTS + 1];
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef CONFIG_USB_HID_BOOT_PROTOCOL
|
||||||
|
u8_t protocol;
|
||||||
|
#endif
|
||||||
} hid_device;
|
} hid_device;
|
||||||
|
|
||||||
static int hid_on_get_idle(struct usb_setup_packet *setup, s32_t *len,
|
static int hid_on_get_idle(struct usb_setup_packet *setup, s32_t *len,
|
||||||
|
@ -133,11 +141,22 @@ static int hid_on_get_report(struct usb_setup_packet *setup, s32_t *len,
|
||||||
static int hid_on_get_protocol(struct usb_setup_packet *setup, s32_t *len,
|
static int hid_on_get_protocol(struct usb_setup_packet *setup, s32_t *len,
|
||||||
u8_t **data)
|
u8_t **data)
|
||||||
{
|
{
|
||||||
LOG_DBG("Get Protocol callback");
|
#ifdef CONFIG_USB_HID_BOOT_PROTOCOL
|
||||||
|
if (setup->wValue) {
|
||||||
|
LOG_ERR("wValue should be 0");
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
|
||||||
/* TODO: Do something. */
|
u32_t size = sizeof(hid_device.protocol);
|
||||||
|
|
||||||
|
LOG_DBG("Get Protocol callback, protocol: %d", hid_device.protocol);
|
||||||
|
|
||||||
|
*data = &hid_device.protocol;
|
||||||
|
len = &size;
|
||||||
|
return 0;
|
||||||
|
#else
|
||||||
return -ENOTSUP;
|
return -ENOTSUP;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static int hid_on_set_idle(struct usb_setup_packet *setup, s32_t *len,
|
static int hid_on_set_idle(struct usb_setup_packet *setup, s32_t *len,
|
||||||
|
@ -205,11 +224,28 @@ static int hid_on_set_report(struct usb_setup_packet *setup, s32_t *len,
|
||||||
static int hid_on_set_protocol(struct usb_setup_packet *setup, s32_t *len,
|
static int hid_on_set_protocol(struct usb_setup_packet *setup, s32_t *len,
|
||||||
u8_t **data)
|
u8_t **data)
|
||||||
{
|
{
|
||||||
LOG_DBG("Set Protocol callback");
|
#ifdef CONFIG_USB_HID_BOOT_PROTOCOL
|
||||||
|
u16_t protocol = sys_le16_to_cpu(setup->wValue);
|
||||||
|
|
||||||
/* TODO: Do something. */
|
if (protocol > HID_PROTOCOL_REPORT) {
|
||||||
|
LOG_ERR("Unsupported protocol: %u", protocol);
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_DBG("Set Protocol callback, protocol: %u", protocol);
|
||||||
|
|
||||||
|
if (hid_device.protocol != protocol) {
|
||||||
|
hid_device.protocol = protocol;
|
||||||
|
|
||||||
|
if (hid_device.ops && hid_device.ops->protocol_change) {
|
||||||
|
hid_device.ops->protocol_change(protocol);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
#else
|
||||||
return -ENOTSUP;
|
return -ENOTSUP;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void usb_set_hid_report_size(u16_t size)
|
static void usb_set_hid_report_size(u16_t size)
|
||||||
|
@ -264,6 +300,9 @@ static void hid_status_cb(enum usb_dc_status_code status, const u8_t *param)
|
||||||
break;
|
break;
|
||||||
case USB_DC_RESET:
|
case USB_DC_RESET:
|
||||||
LOG_DBG("USB device reset detected");
|
LOG_DBG("USB device reset detected");
|
||||||
|
#ifdef CONFIG_USB_HID_BOOT_PROTOCOL
|
||||||
|
hid_device.protocol = HID_PROTOCOL_REPORT;
|
||||||
|
#endif
|
||||||
#ifdef CONFIG_USB_DEVICE_SOF
|
#ifdef CONFIG_USB_DEVICE_SOF
|
||||||
hid_clear_idle_ctx();
|
hid_clear_idle_ctx();
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue