summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Boichat <drinkcat@google.com>2016-11-14 14:45:59 +0800
committerchrome-bot <chrome-bot@chromium.org>2016-11-22 14:52:40 -0800
commitf940d4f51618f00e4d4ee00c95805d0f7ec36bc5 (patch)
treec9c3f969956c0da3e1d88d91a906287c33f3727b
parent481fede513cf43e8bdd145614cd04dd2b2566e17 (diff)
downloadchrome-ec-f940d4f51618f00e4d4ee00c95805d0f7ec36bc5.tar.gz
chip/stm32/usb_hid_keyboard: Add functions for keyscan
This first cleans up the code: - Define report as a structure. - Fix USB interval from 40 ms to 32 ms (Linux kernel complains otherwise). Then, this removes the old set_keyboard_report interface, and replaces it by the interface used by the keyboard scanner (i.e. keyboard_state_changed and keyboard_clear_buffer). This also means we need a keycode table to translate from row/column to USB HID keycode. BRANCH=none BUG=chrome-os-partner:59083 TEST=make buildall -j TEST=make BOARD=hammer -j && util/flash_ec --board=hammer With evtest and "hid 0-7" in console, check that key are reported correctly. Change-Id: I5d526db1568c29c7f28fc5e962e213e44303cc16 Reviewed-on: https://chromium-review.googlesource.com/411571 Commit-Ready: Nicolas Boichat <drinkcat@chromium.org> Tested-by: Nicolas Boichat <drinkcat@chromium.org> Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
-rw-r--r--chip/stm32/usb_hid_keyboard.c137
-rw-r--r--include/usb_hid_keyboard.h14
2 files changed, 97 insertions, 54 deletions
diff --git a/chip/stm32/usb_hid_keyboard.c b/chip/stm32/usb_hid_keyboard.c
index f911779675..38354815c3 100644
--- a/chip/stm32/usb_hid_keyboard.c
+++ b/chip/stm32/usb_hid_keyboard.c
@@ -10,6 +10,8 @@
#include "console.h"
#include "gpio.h"
#include "hooks.h"
+#include "keyboard_config.h"
+#include "keyboard_protocol.h"
#include "link_defs.h"
#include "registers.h"
#include "task.h"
@@ -17,13 +19,46 @@
#include "util.h"
#include "usb_descriptor.h"
#include "usb_hid.h"
-#include "usb_hid_keyboard.h"
#include "usb_hid_hw.h"
/* Console output macro */
#define CPRINTF(format, args...) cprintf(CC_USB, format, ## args)
-#define HID_KEYBOARD_REPORT_SIZE 8
+struct __attribute__((__packed__)) usb_hid_keyboard_report {
+ uint8_t modifiers; /* bitmap of modifiers 224-231 */
+ uint8_t reserved; /* 0x0 */
+ uint8_t keys[6];
+};
+
+#define HID_KEYBOARD_REPORT_SIZE sizeof(struct usb_hid_keyboard_report)
+
+#define HID_KEYBOARD_EP_INTERVAL_MS 32 /* ms */
+
+/* Modifiers keycode range */
+#define HID_KEYBOARD_MODIFIER_LOW 0xe0
+#define HID_KEYBOARD_MODIFIER_HIGH 0xe7
+
+/* The standard Chrome OS keyboard matrix table. See HUT 1.12v2 Table 12 and
+ * https://www.w3.org/TR/DOM-Level-3-Events-code .
+ */
+const uint8_t keycodes[KEYBOARD_ROWS][KEYBOARD_COLS] = {
+ { 0x00, 0xe3, 0x3a, 0x05, 0x43, 0x87, 0x11, 0x00, 0x2e,
+ 0x00, 0xe6, 0x00, 0x00 },
+ { 0x00, 0x29, 0x3d, 0x0a, 0x40, 0x00, 0x0b, 0x00, 0x34,
+ 0x42, 0x00, 0x2a, 0x90 },
+ { 0xe0, 0x2b, 0x3c, 0x17, 0x3f, 0x30, 0x1c, 0x64, 0x2F,
+ 0x41, 0x89, 0x00, 0x00 },
+ { 0x00, 0x35, 0x3b, 0x22, 0x3e, 0x00, 0x23, 0x00, 0x2d,
+ 0x68, 0x00, 0x31, 0x91 },
+ { 0xe4, 0x04, 0x07, 0x09, 0x16, 0x0e, 0x0d, 0x00, 0x33,
+ 0x0f, 0x31, 0x28, 0x00 },
+ { 0x00, 0x1d, 0x06, 0x19, 0x1b, 0x36, 0x10, 0xe1, 0x38,
+ 0x37, 0x00, 0x2c, 0x00 },
+ { 0x00, 0x1e, 0x20, 0x21, 0x1f, 0x25, 0x24, 0x00, 0x27,
+ 0x26, 0xe2, 0x51, 0x4f },
+ { 0x00, 0x14, 0x08, 0x15, 0x1a, 0x0c, 0x18, 0xe5, 0x13,
+ 0x12, 0x00, 0x52, 0x50 }
+};
/* HID descriptors */
const struct usb_interface_descriptor USB_IFACE_DESC(USB_IFACE_HID_KEYBOARD) = {
@@ -43,7 +78,7 @@ const struct usb_endpoint_descriptor USB_EP_DESC(USB_IFACE_HID_KEYBOARD, 81) = {
.bEndpointAddress = 0x80 | USB_EP_HID_KEYBOARD,
.bmAttributes = 0x03 /* Interrupt endpoint */,
.wMaxPacketSize = HID_KEYBOARD_REPORT_SIZE,
- .bInterval = 40 /* ms polling interval */
+ .bInterval = HID_KEYBOARD_EP_INTERVAL_MS /* ms polling interval */
};
/* HID : Report Descriptor */
@@ -51,9 +86,11 @@ static const uint8_t report_desc[] = {
0x05, 0x01, /* Usage Page (Generic Desktop) */
0x09, 0x06, /* Usage (Keyboard) */
0xA1, 0x01, /* Collection (Application) */
+
+ /* Modifiers */
0x05, 0x07, /* Usage Page (Key Codes) */
- 0x19, 0xE0, /* Usage Minimum (224) */
- 0x29, 0xE7, /* Usage Maximum (231) */
+ 0x19, HID_KEYBOARD_MODIFIER_LOW, /* Usage Minimum */
+ 0x29, HID_KEYBOARD_MODIFIER_HIGH, /* Usage Maximum */
0x15, 0x00, /* Logical Minimum (0) */
0x25, 0x01, /* Logical Maximum (1) */
0x75, 0x01, /* Report Size (1) */
@@ -64,13 +101,14 @@ static const uint8_t report_desc[] = {
0x75, 0x08, /* Report Size (8) */
0x81, 0x01, /* Input (Constant), ;Reserved byte */
+ /* Normal keys */
0x95, 0x06, /* Report Count (6) */
0x75, 0x08, /* Report Size (8) */
0x15, 0x00, /* Logical Minimum (0) */
- 0x25, 0x65, /* Logical Maximum(101) */
+ 0x25, 0xa4, /* Logical Maximum (164) */
0x05, 0x07, /* Usage Page (Key Codes) */
0x19, 0x00, /* Usage Minimum (0) */
- 0x29, 0x65, /* Usage Maximum (101) */
+ 0x29, 0xa4, /* Usage Maximum (164) */
0x81, 0x00, /* Input (Data, Array), ;Key arrays (6 bytes) */
0xC0 /* End Collection */
};
@@ -87,12 +125,16 @@ const struct usb_hid_descriptor USB_CUSTOM_DESC(USB_IFACE_HID_KEYBOARD, hid) = {
}}
};
-static usb_uint hid_ep_buf[2][HID_KEYBOARD_REPORT_SIZE / 2] __usb_ram;
+#define EP_BUF_SIZE DIV_ROUND_UP(HID_KEYBOARD_REPORT_SIZE, 2)
+
+static usb_uint hid_ep_buf[2][EP_BUF_SIZE] __usb_ram;
static volatile int hid_current_buf;
static volatile int hid_ep_data_ready;
-void set_keyboard_report(uint64_t rpt)
+static struct usb_hid_keyboard_report report;
+
+static void write_keyboard_report(void)
{
/* Prevent the interrupt handler from sending the data (which would use
* an incomplete buffer).
@@ -100,7 +142,7 @@ void set_keyboard_report(uint64_t rpt)
hid_ep_data_ready = 0;
hid_current_buf = hid_current_buf ? 0 : 1;
memcpy_to_usbram((void *) usb_sram_addr(hid_ep_buf[hid_current_buf]),
- &rpt, sizeof(rpt));
+ &report, sizeof(report));
/* Tell the interrupt handler to send the next buffer. */
hid_ep_data_ready = 1;
@@ -155,42 +197,57 @@ static int hid_keyboard_iface_request(usb_uint *ep0_buf_rx,
}
USB_DECLARE_IFACE(USB_IFACE_HID_KEYBOARD, hid_keyboard_iface_request)
-static int command_hid_kb(int argc, char **argv)
+void keyboard_clear_buffer(void)
{
- uint8_t keycode = 0x0a; /* 'G' key */
+ memset(&report, 0, sizeof(report));
+ write_keyboard_report();
+}
- if (argc >= 2) {
- char *e;
+void keyboard_state_changed(int row, int col, int is_pressed)
+{
+ int i;
+ uint8_t mask;
+ uint8_t keycode = keycodes[row][col];
- keycode = strtoi(argv[1], &e, 16);
- if (*e)
- return EC_ERROR_PARAM1;
+ if (!keycode) {
+ CPRINTF("Unknown key at %d/%d\n", row, col);
+ return;
}
- /* press then release the key */
- set_keyboard_report((uint32_t)keycode << 16);
- udelay(50000);
- set_keyboard_report(0x000000);
-
- return EC_SUCCESS;
-}
-DECLARE_CONSOLE_COMMAND(hid_kb, command_hid_kb,
- "[<HID keycode>]",
- "test USB HID driver");
-
-static int command_hid_test(int argc, char **argv)
-{
- uint8_t keycode = 0x0a; /* 'G' key */
+ if (keycode >= HID_KEYBOARD_MODIFIER_LOW &&
+ keycode <= HID_KEYBOARD_MODIFIER_HIGH) {
+ mask = 0x01 << (keycode - HID_KEYBOARD_MODIFIER_LOW);
+ if (is_pressed)
+ report.modifiers |= mask;
+ else
+ report.modifiers &= ~mask;
- for (keycode = 0x0a; keycode < 0x3a; keycode++) {
- /* Quickly change the report (faster than interrupt period) */
- set_keyboard_report((uint32_t)keycode << 16);
- udelay(1000);
+ write_keyboard_report();
+ return;
}
- udelay(50000);
- set_keyboard_report(0x000000);
- return EC_SUCCESS;
+ if (is_pressed) {
+ /* Add keycode to the list of keys */
+ for (i = 0; i < ARRAY_SIZE(report.keys); i++) {
+ /* Is key already pressed? */
+ if (report.keys[i] == keycode)
+ return;
+ if (report.keys[i] == 0) {
+ report.keys[i] = keycode;
+ write_keyboard_report();
+ return;
+ }
+ }
+ /* Too many keys, ignoring. */
+ } else {
+ /* Remove keycode from the list of keys */
+ for (i = 0; i < ARRAY_SIZE(report.keys); i++) {
+ if (report.keys[i] == keycode) {
+ report.keys[i] = 0;
+ write_keyboard_report();
+ return;
+ }
+ }
+ /* Couldn't find the key... */
+ }
}
-DECLARE_CONSOLE_COMMAND(hid_test, command_hid_test,
- "", "test USB HID driver");
diff --git a/include/usb_hid_keyboard.h b/include/usb_hid_keyboard.h
deleted file mode 100644
index 92d8fd7a25..0000000000
--- a/include/usb_hid_keyboard.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/* Copyright 2016 The Chromium OS Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- *
- * USB HID definitions.
- */
-
-#ifndef __CROS_EC_USB_HID_KEYBOARD_H
-#define __CROS_EC_USB_HID_KEYBOARD_H
-
-/* class implementation interfaces */
-void set_keyboard_report(uint64_t rpt);
-
-#endif