summaryrefslogtreecommitdiffstats
path: root/src/hid.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/hid.c')
-rw-r--r--src/hid.c126
1 files changed, 126 insertions, 0 deletions
diff --git a/src/hid.c b/src/hid.c
new file mode 100644
index 0000000..8feb1cb
--- /dev/null
+++ b/src/hid.c
@@ -0,0 +1,126 @@
+#include "project.h"
+
+static const uint8_t hid_report_descriptor[] = {
+ 0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */
+ 0x09, 0x02, /* USAGE (Mouse) */
+ 0xa1, 0x01, /* COLLECTION (Application) */
+ 0x09, 0x01, /* USAGE (Pointer) */
+ 0xa1, 0x00, /* COLLECTION (Physical) */
+ 0x05, 0x09, /* USAGE_PAGE (Button) */
+ 0x19, 0x01, /* USAGE_MINIMUM (Button 1) */
+ 0x29, 0x03, /* USAGE_MAXIMUM (Button 3) */
+ 0x15, 0x00, /* LOGICAL_MINIMUM (0) */
+ 0x25, 0x01, /* LOGICAL_MAXIMUM (1) */
+ 0x95, 0x03, /* REPORT_COUNT (3) */
+ 0x75, 0x01, /* REPORT_SIZE (1) */
+ 0x81, 0x02, /* INPUT (Data,Var,Abs) */
+ 0x95, 0x01, /* REPORT_COUNT (1) */
+ 0x75, 0x05, /* REPORT_SIZE (5) */
+ 0x81, 0x01, /* INPUT (Cnst,Ary,Abs) */
+ 0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */
+ 0x09, 0x30, /* USAGE (X) */
+ 0x09, 0x31, /* USAGE (Y) */
+ 0x09, 0x38, /* USAGE (Wheel) */
+ 0x15, 0x81, /* LOGICAL_MINIMUM (-127) */
+ 0x25, 0x7f, /* LOGICAL_MAXIMUM (127) */
+ 0x75, 0x08, /* REPORT_SIZE (8) */
+ 0x95, 0x03, /* REPORT_COUNT (3) */
+ 0x81, 0x06, /* INPUT (Data,Var,Rel) */
+ 0xc0, /* END_COLLECTION */
+ 0x09, 0x3c, /* USAGE (Motion Wakeup) */
+ 0x05, 0xff, /* USAGE_PAGE (Vendor Defined Page 1) */
+ 0x09, 0x01, /* USAGE (Vendor Usage 1) */
+ 0x15, 0x00, /* LOGICAL_MINIMUM (0) */
+ 0x25, 0x01, /* LOGICAL_MAXIMUM (1) */
+ 0x75, 0x01, /* REPORT_SIZE (1) */
+ 0x95, 0x02, /* REPORT_COUNT (2) */
+ 0xb1, 0x22, /* FEATURE (Data,Var,Abs,NPrf) */
+ 0x75, 0x06, /* REPORT_SIZE (6) */
+ 0x95, 0x01, /* REPORT_COUNT (1) */
+ 0xb1, 0x01, /* FEATURE (Cnst,Ary,Abs) */
+ 0xc0 /* END_COLLECTION */
+};
+
+static const struct {
+ struct usb_hid_descriptor hid_descriptor;
+ struct {
+ uint8_t bReportDescriptorType;
+ uint16_t wDescriptorLength;
+ } __attribute__((packed)) hid_report;
+} __attribute__((packed)) hid_function = {
+ .hid_descriptor = {
+ .bLength = sizeof(hid_function),
+ .bDescriptorType = USB_DT_HID,
+ .bcdHID = 0x0100,
+ .bCountryCode = 0,
+ .bNumDescriptors = 1,
+ },
+ .hid_report = {
+ .bReportDescriptorType = USB_DT_REPORT,
+ .wDescriptorLength = sizeof(hid_report_descriptor),
+ },
+};
+
+const struct usb_endpoint_descriptor hid_endpoint = {
+ .bLength = USB_DT_ENDPOINT_SIZE,
+ .bDescriptorType = USB_DT_ENDPOINT,
+ .bEndpointAddress = 0x81,
+ .bmAttributes = USB_ENDPOINT_ATTR_INTERRUPT,
+ .wMaxPacketSize = 4,
+ .bInterval = 0x20,
+};
+
+const struct usb_interface_descriptor hid_iface = {
+ .bLength = USB_DT_INTERFACE_SIZE,
+ .bDescriptorType = USB_DT_INTERFACE,
+ .bInterfaceNumber = 0,
+ .bAlternateSetting = 0,
+ .bNumEndpoints = 1,
+ .bInterfaceClass = USB_CLASS_HID,
+ .bInterfaceSubClass = 1, /* boot */
+ .bInterfaceProtocol = 2, /* mouse */
+ .iInterface = 0,
+
+ .endpoint = &hid_endpoint,
+
+ .extra = &hid_function,
+ .extralen = sizeof(hid_function),
+};
+
+/* Buffer to be used for control requests. */
+uint8_t usbd_control_buffer[128];
+
+int hid_control_request(usbd_device *usbd_dev, struct usb_setup_data *req, uint8_t **buf, uint16_t *len,
+ void (**complete)(usbd_device *usbd_dev, struct usb_setup_data *req))
+{
+ (void)complete;
+ (void)usbd_dev;
+
+ if ((req->bmRequestType != 0x81) ||
+ (req->bRequest != USB_REQ_GET_DESCRIPTOR) ||
+ (req->wValue != 0x2200))
+ return 0;
+
+ /* Handle the HID report descriptor. */
+ *buf = (uint8_t *)hid_report_descriptor;
+ *len = sizeof(hid_report_descriptor);
+
+ return 1;
+}
+
+void hid_test(void)
+{
+ static int x = 0;
+ static int dir = 1;
+ uint8_t buf[4] = {0, 0, 0, 0};
+
+ buf[1] = dir;
+ x += dir;
+ if (x > 30)
+ dir = -dir;
+ if (x < -30)
+ dir = -dir;
+
+ usbd_ep_write_packet(usbd_dev, 0x81, buf, 4);
+}
+