|
@@ -15,6 +15,12 @@
|
|
|
#include <dm/uclass-internal.h>
|
|
|
#include <test/ut.h>
|
|
|
|
|
|
+struct keyboard_test_data {
|
|
|
+ const char modifiers;
|
|
|
+ const char scancode;
|
|
|
+ const char result[6];
|
|
|
+};
|
|
|
+
|
|
|
/* Test that sandbox USB works correctly */
|
|
|
static int dm_test_usb_base(struct unit_test_state *uts)
|
|
|
{
|
|
@@ -115,9 +121,263 @@ static int dm_test_usb_stop(struct unit_test_state *uts)
|
|
|
}
|
|
|
DM_TEST(dm_test_usb_stop, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
|
|
|
|
|
|
+/**
|
|
|
+ * dm_test_usb_keyb() - test USB keyboard driver
|
|
|
+ *
|
|
|
+ * This test copies USB keyboard scan codes into the key buffer of the USB
|
|
|
+ * keyboard emulation driver. These are picked up during emulated interrupts
|
|
|
+ * by the USB keyboard driver and converted to characters and escape sequences.
|
|
|
+ * The test then reads and verifies these characters and escape sequences from
|
|
|
+ * the standard input.
|
|
|
+ *
|
|
|
+ * TODO: The following features are not yet tested:
|
|
|
+ *
|
|
|
+ * * LED status
|
|
|
+ * * caps-lock
|
|
|
+ * * num-lock
|
|
|
+ * * numerical pad keys
|
|
|
+ *
|
|
|
+ * TODO: The following features are not yet implemented by the USB keyboard
|
|
|
+ * driver and therefore not tested:
|
|
|
+ *
|
|
|
+ * * modifiers for non-alpha-numeric keys, e.g. <SHIFT><TAB> and <ALT><F4>
|
|
|
+ * * some special keys, e.g. <PRINT>
|
|
|
+ * * some modifiers, e.g. <ALT> and <META>
|
|
|
+ * * alternative keyboard layouts
|
|
|
+ *
|
|
|
+ * @uts: unit test state
|
|
|
+ * Return: 0 on success
|
|
|
+ */
|
|
|
static int dm_test_usb_keyb(struct unit_test_state *uts)
|
|
|
{
|
|
|
struct udevice *dev;
|
|
|
+ const struct keyboard_test_data *pos;
|
|
|
+ const struct keyboard_test_data kbd_test_data[] = {
|
|
|
+ /* <A> */
|
|
|
+ {0x00, 0x04, "a"},
|
|
|
+ /* <B> */
|
|
|
+ {0x00, 0x05, "b"},
|
|
|
+ /* <C> */
|
|
|
+ {0x00, 0x06, "c"},
|
|
|
+ /* <D> */
|
|
|
+ {0x00, 0x07, "d"},
|
|
|
+ /* <E> */
|
|
|
+ {0x00, 0x08, "e"},
|
|
|
+ /* <F> */
|
|
|
+ {0x00, 0x09, "f"},
|
|
|
+ /* <G> */
|
|
|
+ {0x00, 0x0a, "g"},
|
|
|
+ /* <H> */
|
|
|
+ {0x00, 0x0b, "h"},
|
|
|
+ /* <I> */
|
|
|
+ {0x00, 0x0c, "i"},
|
|
|
+ /* <J> */
|
|
|
+ {0x00, 0x0d, "j"},
|
|
|
+ /* <K> */
|
|
|
+ {0x00, 0x0e, "k"},
|
|
|
+ /* <L> */
|
|
|
+ {0x00, 0x0f, "l"},
|
|
|
+ /* <M> */
|
|
|
+ {0x00, 0x10, "m"},
|
|
|
+ /* <N> */
|
|
|
+ {0x00, 0x11, "n"},
|
|
|
+ /* <O> */
|
|
|
+ {0x00, 0x12, "o"},
|
|
|
+ /* <P> */
|
|
|
+ {0x00, 0x13, "p"},
|
|
|
+ /* <Q> */
|
|
|
+ {0x00, 0x14, "q"},
|
|
|
+ /* <R> */
|
|
|
+ {0x00, 0x15, "r"},
|
|
|
+ /* <S> */
|
|
|
+ {0x00, 0x16, "s"},
|
|
|
+ /* <T> */
|
|
|
+ {0x00, 0x17, "t"},
|
|
|
+ /* <U> */
|
|
|
+ {0x00, 0x18, "u"},
|
|
|
+ /* <V> */
|
|
|
+ {0x00, 0x19, "v"},
|
|
|
+ /* <W> */
|
|
|
+ {0x00, 0x1a, "w"},
|
|
|
+ /* <X> */
|
|
|
+ {0x00, 0x1b, "x"},
|
|
|
+ /* <Y> */
|
|
|
+ {0x00, 0x1c, "y"},
|
|
|
+ /* <Z> */
|
|
|
+ {0x00, 0x1d, "z"},
|
|
|
+
|
|
|
+ /* <LEFT-SHIFT><A> */
|
|
|
+ {0x02, 0x04, "A"},
|
|
|
+ /* <RIGHT-SHIFT><Z> */
|
|
|
+ {0x20, 0x1d, "Z"},
|
|
|
+
|
|
|
+ /* <LEFT-CONTROL><A> */
|
|
|
+ {0x01, 0x04, "\x01"},
|
|
|
+ /* <RIGHT-CONTROL><Z> */
|
|
|
+ {0x10, 0x1d, "\x1a"},
|
|
|
+
|
|
|
+ /* <1> */
|
|
|
+ {0x00, 0x1e, "1"},
|
|
|
+ /* <2> */
|
|
|
+ {0x00, 0x1f, "2"},
|
|
|
+ /* <3> */
|
|
|
+ {0x00, 0x20, "3"},
|
|
|
+ /* <4> */
|
|
|
+ {0x00, 0x21, "4"},
|
|
|
+ /* <5> */
|
|
|
+ {0x00, 0x22, "5"},
|
|
|
+ /* <6> */
|
|
|
+ {0x00, 0x23, "6"},
|
|
|
+ /* <7> */
|
|
|
+ {0x00, 0x24, "7"},
|
|
|
+ /* <8> */
|
|
|
+ {0x00, 0x25, "8"},
|
|
|
+ /* <9> */
|
|
|
+ {0x00, 0x26, "9"},
|
|
|
+ /* <0> */
|
|
|
+ {0x00, 0x27, "0"},
|
|
|
+
|
|
|
+ /* <LEFT-SHIFT><1> */
|
|
|
+ {0x02, 0x1e, "!"},
|
|
|
+ /* <RIGHT-SHIFT><2> */
|
|
|
+ {0x20, 0x1f, "@"},
|
|
|
+ /* <LEFT-SHIFT><3> */
|
|
|
+ {0x02, 0x20, "#"},
|
|
|
+ /* <RIGHT-SHIFT><4> */
|
|
|
+ {0x20, 0x21, "$"},
|
|
|
+ /* <LEFT-SHIFT><5> */
|
|
|
+ {0x02, 0x22, "%"},
|
|
|
+ /* <RIGHT-SHIFT><6> */
|
|
|
+ {0x20, 0x23, "^"},
|
|
|
+ /* <LEFT-SHIFT><7> */
|
|
|
+ {0x02, 0x24, "&"},
|
|
|
+ /* <RIGHT-SHIFT><8> */
|
|
|
+ {0x20, 0x25, "*"},
|
|
|
+ /* <LEFT-SHIFT><9> */
|
|
|
+ {0x02, 0x26, "("},
|
|
|
+ /* <RIGHT-SHIFT><0> */
|
|
|
+ {0x20, 0x27, ")"},
|
|
|
+
|
|
|
+ /* <ENTER> */
|
|
|
+ {0x00, 0x28, "\r"},
|
|
|
+ /* <ESCAPE> */
|
|
|
+ {0x00, 0x29, "\x1b"},
|
|
|
+ /* <BACKSPACE> */
|
|
|
+ {0x00, 0x2a, "\x08"},
|
|
|
+ /* <TAB> */
|
|
|
+ {0x00, 0x2b, "\x09"},
|
|
|
+ /* <SPACE> */
|
|
|
+ {0x00, 0x2c, " "},
|
|
|
+ /* <MINUS> */
|
|
|
+ {0x00, 0x2d, "-"},
|
|
|
+ /* <EQUAL> */
|
|
|
+ {0x00, 0x2e, "="},
|
|
|
+ /* <LEFT BRACE> */
|
|
|
+ {0x00, 0x2f, "["},
|
|
|
+ /* <RIGHT BRACE> */
|
|
|
+ {0x00, 0x30, "]"},
|
|
|
+ /* <BACKSLASH> */
|
|
|
+ {0x00, 0x31, "\\"},
|
|
|
+ /* <HASH-TILDE> */
|
|
|
+ {0x00, 0x32, "#"},
|
|
|
+ /* <SEMICOLON> */
|
|
|
+ {0x00, 0x33, ";"},
|
|
|
+ /* <APOSTROPHE> */
|
|
|
+ {0x00, 0x34, "'"},
|
|
|
+ /* <GRAVE> */
|
|
|
+ {0x00, 0x35, "`"},
|
|
|
+ /* <COMMA> */
|
|
|
+ {0x00, 0x36, ","},
|
|
|
+ /* <DOT> */
|
|
|
+ {0x00, 0x37, "."},
|
|
|
+ /* <SLASH> */
|
|
|
+ {0x00, 0x38, "/"},
|
|
|
+
|
|
|
+ /* <LEFT-SHIFT><ENTER> */
|
|
|
+ {0x02, 0x28, "\r"},
|
|
|
+ /* <RIGHT-SHIFT><ESCAPE> */
|
|
|
+ {0x20, 0x29, "\x1b"},
|
|
|
+ /* <LEFT-SHIFT><BACKSPACE> */
|
|
|
+ {0x02, 0x2a, "\x08"},
|
|
|
+ /* <RIGHT-SHIFT><TAB> */
|
|
|
+ {0x20, 0x2b, "\x09"},
|
|
|
+ /* <LEFT-SHIFT><SPACE> */
|
|
|
+ {0x02, 0x2c, " "},
|
|
|
+ /* <MINUS> */
|
|
|
+ {0x20, 0x2d, "_"},
|
|
|
+ /* <LEFT-SHIFT><EQUAL> */
|
|
|
+ {0x02, 0x2e, "+"},
|
|
|
+ /* <RIGHT-SHIFT><LEFT BRACE> */
|
|
|
+ {0x20, 0x2f, "{"},
|
|
|
+ /* <LEFT-SHIFT><RIGHT BRACE> */
|
|
|
+ {0x02, 0x30, "}"},
|
|
|
+ /* <RIGHT-SHIFT><BACKSLASH> */
|
|
|
+ {0x20, 0x31, "|"},
|
|
|
+ /* <LEFT-SHIFT><HASH-TILDE> */
|
|
|
+ {0x02, 0x32, "~"},
|
|
|
+ /* <RIGHT-SHIFT><SEMICOLON> */
|
|
|
+ {0x20, 0x33, ":"},
|
|
|
+ /* <LEFT-SHIFT><APOSTROPHE> */
|
|
|
+ {0x02, 0x34, "\""},
|
|
|
+ /* <RIGHT-SHIFT><GRAVE> */
|
|
|
+ {0x20, 0x35, "~"},
|
|
|
+ /* <LEFT-SHIFT><COMMA> */
|
|
|
+ {0x02, 0x36, "<"},
|
|
|
+ /* <RIGHT-SHIFT><DOT> */
|
|
|
+ {0x20, 0x37, ">"},
|
|
|
+ /* <LEFT-SHIFT><SLASH> */
|
|
|
+ {0x02, 0x38, "?"},
|
|
|
+#ifdef CONFIG_USB_KEYBOARD_FN_KEYS
|
|
|
+ /* <F1> */
|
|
|
+ {0x00, 0x3a, "\x1bOP"},
|
|
|
+ /* <F2> */
|
|
|
+ {0x00, 0x3b, "\x1bOQ"},
|
|
|
+ /* <F3> */
|
|
|
+ {0x00, 0x3c, "\x1bOR"},
|
|
|
+ /* <F4> */
|
|
|
+ {0x00, 0x3d, "\x1bOS"},
|
|
|
+ /* <F5> */
|
|
|
+ {0x00, 0x3e, "\x1b[15~"},
|
|
|
+ /* <F6> */
|
|
|
+ {0x00, 0x3f, "\x1b[17~"},
|
|
|
+ /* <F7> */
|
|
|
+ {0x00, 0x40, "\x1b[18~"},
|
|
|
+ /* <F8> */
|
|
|
+ {0x00, 0x41, "\x1b[19~"},
|
|
|
+ /* <F9> */
|
|
|
+ {0x00, 0x42, "\x1b[20~"},
|
|
|
+ /* <F10> */
|
|
|
+ {0x00, 0x43, "\x1b[21~"},
|
|
|
+ /* <F11> */
|
|
|
+ {0x00, 0x44, "\x1b[23~"},
|
|
|
+ /* <F12> */
|
|
|
+ {0x00, 0x45, "\x1b[24~"},
|
|
|
+ /* <INSERT> */
|
|
|
+ {0x00, 0x49, "\x1b[2~"},
|
|
|
+ /* <HOME> */
|
|
|
+ {0x00, 0x4a, "\x1b[H"},
|
|
|
+ /* <PAGE UP> */
|
|
|
+ {0x00, 0x4b, "\x1b[5~"},
|
|
|
+ /* <DELETE> */
|
|
|
+ {0x00, 0x4c, "\x1b[3~"},
|
|
|
+ /* <END> */
|
|
|
+ {0x00, 0x4d, "\x1b[F"},
|
|
|
+ /* <PAGE DOWN> */
|
|
|
+ {0x00, 0x4e, "\x1b[6~"},
|
|
|
+ /* <RIGHT> */
|
|
|
+ {0x00, 0x4f, "\x1b[C"},
|
|
|
+ /* <LEFT> */
|
|
|
+ {0x00, 0x50, "\x1b[D"},
|
|
|
+ /* <DOWN> */
|
|
|
+ {0x00, 0x51, "\x1b[B"},
|
|
|
+ /* <UP> */
|
|
|
+ {0x00, 0x52, "\x1b[A"},
|
|
|
+#endif /* CONFIG_USB_KEYBOARD_FN_KEYS */
|
|
|
+
|
|
|
+ /* End of list */
|
|
|
+ {0x00, 0x00, "\0"}
|
|
|
+ };
|
|
|
+
|
|
|
|
|
|
state_set_skip_delays(true);
|
|
|
ut_assertok(usb_init());
|
|
@@ -129,16 +389,24 @@ static int dm_test_usb_keyb(struct unit_test_state *uts)
|
|
|
&dev));
|
|
|
|
|
|
/*
|
|
|
- * Add a string to the USB keyboard buffer - it should appear in
|
|
|
- * stdin
|
|
|
+ * Add scan codes to the USB keyboard buffer. They should appear as
|
|
|
+ * corresponding characters and escape sequences in stdin.
|
|
|
*/
|
|
|
- ut_assertok(sandbox_usb_keyb_add_string(dev, "ab"));
|
|
|
- ut_asserteq(1, tstc());
|
|
|
- ut_asserteq('a', getc());
|
|
|
- ut_asserteq(1, tstc());
|
|
|
- ut_asserteq('b', getc());
|
|
|
- ut_asserteq(0, tstc());
|
|
|
+ for (pos = kbd_test_data; pos->scancode; ++pos) {
|
|
|
+ const char *c;
|
|
|
+ char scancodes[USB_KBD_BOOT_REPORT_SIZE] = {0};
|
|
|
+
|
|
|
+ scancodes[0] = pos->modifiers;
|
|
|
+ scancodes[2] = pos->scancode;
|
|
|
|
|
|
+ ut_assertok(sandbox_usb_keyb_add_string(dev, scancodes));
|
|
|
+
|
|
|
+ for (c = pos->result; *c; ++c) {
|
|
|
+ ut_asserteq(1, tstc());
|
|
|
+ ut_asserteq(*c, getc());
|
|
|
+ }
|
|
|
+ ut_asserteq(0, tstc());
|
|
|
+ }
|
|
|
ut_assertok(usb_stop());
|
|
|
|
|
|
return 0;
|