Quellcode durchsuchen

enhance device hid

- add CFG_TUD_HID_ASCII_TO_KEYCODE_LOOKUP
- add tud_hid_keyboard_send_keycode(), tud_hid_keyboard_send_char(),
tud_hid_keyboard_send_string()
- add timeout_blocking_wait()
hathach vor 7 Jahren
Ursprung
Commit
3e209f9c20

+ 27 - 0
examples/device/nrf52840/src/main.c

@@ -76,6 +76,9 @@ int main(void)
   return 0;
 }
 
+//--------------------------------------------------------------------+
+// USB CDC
+//--------------------------------------------------------------------+
 void virtual_com_task(void)
 {
   // connected and there are data available
@@ -91,6 +94,30 @@ void virtual_com_task(void)
   }
 }
 
+//--------------------------------------------------------------------+
+// USB CDC
+//--------------------------------------------------------------------+
+void usb_hid_task(void)
+{
+  if ( tud_mounted() )
+  {
+    if ( !tud_hid_keyboard_busy() )
+    {
+      static bool toggle = false; // send either A or B
+
+      tud_hid_keyboard_send_char( toggle ? 'A' : 'B' );
+      toggle = !toggle;
+    }
+
+    if ( !tud_hid_mouse_busy() )
+    {
+
+    }
+
+  }
+}
+
+
 
 //--------------------------------------------------------------------+
 // tinyusb callbacks

+ 7 - 0
examples/device/nrf52840/src/tusb_config.h

@@ -126,6 +126,13 @@
  */
 #define CFG_TUD_HID_BOOT_PROTOCOL   1
 
+/* Use the HID_ASCII_TO_KEYCODE lookup if CFG_TUD_HID_KEYBOARD is enabled.
+ * This will occupies 256 bytes of ROM. It will also enable the use of 2 extra APIs
+ * - tud_hid_keyboard_send_char()
+ * - tud_hid_keyboard_send_string()
+ */
+#define CFG_TUD_HID_ASCII_TO_KEYCODE_LOOKUP 1
+
 //--------------------------------------------------------------------
 // USB RAM PLACEMENT
 //--------------------------------------------------------------------

+ 116 - 95
src/class/hid/hid.h

@@ -217,101 +217,122 @@ typedef enum
 
 /// @}
 
-#define HID_KEYCODE_TABLE(ENTRY) \
-    ENTRY( 0x04, 'a'   , 'A'    )\
-    ENTRY( 0x05, 'b'   , 'B'    )\
-    ENTRY( 0x06, 'c'   , 'C'    )\
-    ENTRY( 0x07, 'd'   , 'D'    )\
-    ENTRY( 0x08, 'e'   , 'E'    )\
-    ENTRY( 0x09, 'f'   , 'F'    )\
-    ENTRY( 0x0a, 'g'   , 'G'    )\
-    ENTRY( 0x0b, 'h'   , 'H'    )\
-    ENTRY( 0x0c, 'i'   , 'I'    )\
-    ENTRY( 0x0d, 'j'   , 'J'    )\
-    ENTRY( 0x0e, 'k'   , 'K'    )\
-    ENTRY( 0x0f, 'l'   , 'L'    )\
-    ENTRY( 0x10, 'm'   , 'M'    )\
-    ENTRY( 0x11, 'n'   , 'N'    )\
-    ENTRY( 0x12, 'o'   , 'O'    )\
-    ENTRY( 0x13, 'p'   , 'P'    )\
-    ENTRY( 0x14, 'q'   , 'Q'    )\
-    ENTRY( 0x15, 'r'   , 'R'    )\
-    ENTRY( 0x16, 's'   , 'S'    )\
-    ENTRY( 0x17, 't'   , 'T'    )\
-    ENTRY( 0x18, 'u'   , 'U'    )\
-    ENTRY( 0x19, 'v'   , 'V'    )\
-    ENTRY( 0x1a, 'w'   , 'W'    )\
-    ENTRY( 0x1b, 'x'   , 'X'    )\
-    ENTRY( 0x1c, 'y'   , 'Y'    )\
-    ENTRY( 0x1d, 'z'   , 'Z'    )\
-    \
-    ENTRY( 0x1e, '1'   , '!'    )\
-    ENTRY( 0x1f, '2'   , '@'    )\
-    ENTRY( 0x20, '3'   , '#'    )\
-    ENTRY( 0x21, '4'   , '$'    )\
-    ENTRY( 0x22, '5'   , '%'    )\
-    ENTRY( 0x23, '6'   , '^'    )\
-    ENTRY( 0x24, '7'   , '&'    )\
-    ENTRY( 0x25, '8'   , '*'    )\
-    ENTRY( 0x26, '9'   , '('    )\
-    ENTRY( 0x27, '0'   , ')'    )\
-    \
-    ENTRY( 0x28, '\r'  , '\r'   )\
-    ENTRY( 0x29, '\x1b', '\x1b' )\
-    ENTRY( 0x2a, '\b'  , '\b'   )\
-    ENTRY( 0x2b, '\t'  , '\t'   )\
-    ENTRY( 0x2c, ' '   , ' '    )\
-    ENTRY( 0x2d, '-'   , '_'    )\
-    ENTRY( 0x2e, '='   , '+'    )\
-    ENTRY( 0x2f, '['   , '{'    )\
-    ENTRY( 0x30, ']'   , '}'    )\
-    ENTRY( 0x31, '\\'  , '|'    )\
-    ENTRY( 0x32, '#'   , '~'    ) /* TODO non-US keyboard */ \
-    ENTRY( 0x33, ';'   , ':'    )\
-    ENTRY( 0x34, '\''  , '\"'   )\
-    ENTRY( 0x35, 0     , 0      )\
-    ENTRY( 0x36, ','   , '<'    )\
-    ENTRY( 0x37, '.'   , '>'    )\
-    ENTRY( 0x38, '/'   , '?'    )\
-    ENTRY( 0x39, 0     , 0      ) /* TODO CapsLock, non-locking key implementation*/ \
-    \
-    ENTRY( 0x54, '/'   , '/'    )\
-    ENTRY( 0x55, '*'   , '*'    )\
-    ENTRY( 0x56, '-'   , '-'    )\
-    ENTRY( 0x57, '+'   , '+'    )\
-    ENTRY( 0x58, '\r'  , '\r'   )\
-    ENTRY( 0x59, '1'   , 0      ) /* numpad1 & end */ \
-    ENTRY( 0x5a, '2'   , 0      )\
-    ENTRY( 0x5b, '3'   , 0      )\
-    ENTRY( 0x5c, '4'   , 0      )\
-    ENTRY( 0x5d, '5'   , '5'    )\
-    ENTRY( 0x5e, '6'   , 0      )\
-    ENTRY( 0x5f, '7'   , 0      )\
-    ENTRY( 0x60, '8'   , 0      )\
-    ENTRY( 0x61, '9'   , 0      )\
-    ENTRY( 0x62, '0'   , 0      )\
-    ENTRY( 0x63, '0'   , 0      )\
-    ENTRY( 0x67, '='   , '='    )\
-
-
-
-// TODO HID complete keycode table
-
-//enum
-//{
-//  KEYBOARD_KEYCODE_A     = 0x04,
-//  KEYBOARD_KEYCODE_Z     = 0x1d,
-//
-//  KEYBOARD_KEYCODE_1     = 0x1e,
-//  KEYBOARD_KEYCODE_0     = 0x27,
-//
-//  KEYBOARD_KEYCODE_ENTER = 0x28,
-//  KEYBOARD_KEYCODE_ESCAPE = 0x29,
-//  KEYBOARD_KEYCODE_BACKSPACE = 0x2a,
-//  KEYBOARD_KEYCODE_TAB = 0x2b,
-//  KEYBOARD_KEYCODE_SPACEBAR = 0x2c,
-//
-//};
+//--------------------------------------------------------------------+
+// HID KEYCODE
+//--------------------------------------------------------------------+
+#define HID_KEY_NONE               0x00
+#define HID_KEY_A                  0x04
+#define HID_KEY_B                  0x05
+#define HID_KEY_C                  0x06
+#define HID_KEY_D                  0x07
+#define HID_KEY_E                  0x08
+#define HID_KEY_F                  0x09
+#define HID_KEY_G                  0x0A
+#define HID_KEY_H                  0x0B
+#define HID_KEY_I                  0x0C
+#define HID_KEY_J                  0x0D
+#define HID_KEY_K                  0x0E
+#define HID_KEY_L                  0x0F
+#define HID_KEY_M                  0x10
+#define HID_KEY_N                  0x11
+#define HID_KEY_O                  0x12
+#define HID_KEY_P                  0x13
+#define HID_KEY_Q                  0x14
+#define HID_KEY_R                  0x15
+#define HID_KEY_S                  0x16
+#define HID_KEY_T                  0x17
+#define HID_KEY_U                  0x18
+#define HID_KEY_V                  0x19
+#define HID_KEY_W                  0x1A
+#define HID_KEY_X                  0x1B
+#define HID_KEY_Y                  0x1C
+#define HID_KEY_Z                  0x1D
+#define HID_KEY_1                  0x1E
+#define HID_KEY_2                  0x1F
+#define HID_KEY_3                  0x20
+#define HID_KEY_4                  0x21
+#define HID_KEY_5                  0x22
+#define HID_KEY_6                  0x23
+#define HID_KEY_7                  0x24
+#define HID_KEY_8                  0x25
+#define HID_KEY_9                  0x26
+#define HID_KEY_0                  0x27
+#define HID_KEY_RETURN             0x28
+#define HID_KEY_ESCAPE             0x29
+#define HID_KEY_BACKSPACE          0x2A
+#define HID_KEY_TAB                0x2B
+#define HID_KEY_SPACE              0x2C
+#define HID_KEY_MINUS              0x2D
+#define HID_KEY_EQUAL              0x2E
+#define HID_KEY_BRACKET_LEFT       0x2F
+#define HID_KEY_BRACKET_RIGHT      0x30
+#define HID_KEY_BACKSLASH          0x31
+#define HID_KEY_EUROPE_1           0x32
+#define HID_KEY_SEMICOLON          0x33
+#define HID_KEY_APOSTROPHE         0x34
+#define HID_KEY_GRAVE              0x35
+#define HID_KEY_COMMA              0x36
+#define HID_KEY_PERIOD             0x37
+#define HID_KEY_SLASH              0x38
+#define HID_KEY_CAPS_LOCK          0x39
+#define HID_KEY_F1                 0x3A
+#define HID_KEY_F2                 0x3B
+#define HID_KEY_F3                 0x3C
+#define HID_KEY_F4                 0x3D
+#define HID_KEY_F5                 0x3E
+#define HID_KEY_F6                 0x3F
+#define HID_KEY_F7                 0x40
+#define HID_KEY_F8                 0x41
+#define HID_KEY_F9                 0x42
+#define HID_KEY_F10                0x43
+#define HID_KEY_F11                0x44
+#define HID_KEY_F12                0x45
+#define HID_KEY_PRINT_SCREEN       0x46
+#define HID_KEY_SCROLL_LOCK        0x47
+#define HID_KEY_PAUSE              0x48
+#define HID_KEY_INSERT             0x49
+#define HID_KEY_HOME               0x4A
+#define HID_KEY_PAGE_UP            0x4B
+#define HID_KEY_DELETE             0x4C
+#define HID_KEY_END                0x4D
+#define HID_KEY_PAGE_DOWN          0x4E
+#define HID_KEY_ARROW_RIGHT        0x4F
+#define HID_KEY_ARROW_LEFT         0x50
+#define HID_KEY_ARROW_DOWN         0x51
+#define HID_KEY_ARROW_UP           0x52
+#define HID_KEY_NUM_LOCK           0x53
+#define HID_KEY_KEYPAD_DIVIDE      0x54
+#define HID_KEY_KEYPAD_MULTIPLY    0x55
+#define HID_KEY_KEYPAD_SUBTRACT    0x56
+#define HID_KEY_KEYPAD_ADD         0x57
+#define HID_KEY_KEYPAD_ENTER       0x58
+#define HID_KEY_KEYPAD_1           0x59
+#define HID_KEY_KEYPAD_2           0x5A
+#define HID_KEY_KEYPAD_3           0x5B
+#define HID_KEY_KEYPAD_4           0x5C
+#define HID_KEY_KEYPAD_5           0x5D
+#define HID_KEY_KEYPAD_6           0x5E
+#define HID_KEY_KEYPAD_7           0x5F
+#define HID_KEY_KEYPAD_8           0x60
+#define HID_KEY_KEYPAD_9           0x61
+#define HID_KEY_KEYPAD_0           0x62
+#define HID_KEY_KEYPAD_DECIMAL     0x63
+#define HID_KEY_EUROPE_2           0x64
+#define HID_KEY_APPLICATION        0x65
+#define HID_KEY_POWER              0x66
+#define HID_KEY_KEYPAD_EQUAL       0x67
+#define HID_KEY_F13                0x68
+#define HID_KEY_F14                0x69
+#define HID_KEY_F15                0x6A
+#define HID_KEY_CONTROL_LEFT       0xE0
+#define HID_KEY_SHIFT_LEFT         0xE1
+#define HID_KEY_ALT_LEFT           0xE2
+#define HID_KEY_GUI_LEFT           0xE3
+#define HID_KEY_CONTROL_RIGHT      0xE4
+#define HID_KEY_SHIFT_RIGHT        0xE5
+#define HID_KEY_ALT_RIGHT          0xE6
+#define HID_KEY_GUI_RIGHT          0xE7
+
 
 //--------------------------------------------------------------------+
 // REPORT DESCRIPTOR

+ 205 - 11
src/class/hid/hid_device.c

@@ -45,6 +45,7 @@
 // INCLUDE
 //--------------------------------------------------------------------+
 #include "common/tusb_common.h"
+#include "common/timeout_timer.h"
 #include "hid_device.h"
 #include "device/usbd_pvt.h"
 
@@ -91,16 +92,71 @@ bool tud_hid_keyboard_busy(void)
   return dcd_edpt_busy(TUD_OPT_RHPORT, _kbd_itf.ep_in);
 }
 
-tusb_error_t tud_hid_keyboard_send(hid_keyboard_report_t const *p_report)
+bool tud_hid_keyboard_send_report(hid_keyboard_report_t const *p_report)
 {
-  VERIFY(tud_mounted(), TUSB_ERROR_USBD_DEVICE_NOT_CONFIGURED);
+  VERIFY( tud_mounted() && !tud_hid_keyboard_busy() );
 
-  hidd_interface_t * p_kbd = &_kbd_itf;
+  hidd_interface_t * p_hid = &_kbd_itf;
 
-  TU_ASSERT( dcd_edpt_xfer(TUD_OPT_RHPORT, p_kbd->ep_in, (void*) p_report, sizeof(hid_keyboard_report_t)), TUSB_ERROR_DCD_EDPT_XFER ) ;
+  if ( p_report )
+  {
+    memcpy(p_hid->report_buf, p_report, sizeof(hid_keyboard_report_t));
+  }else
+  {
+    // empty report
+    arrclr_(p_hid->report_buf);
+  }
 
-  return TUSB_ERROR_NONE;
+  return dcd_edpt_xfer(TUD_OPT_RHPORT, p_hid->ep_in, p_hid->report_buf, sizeof(hid_keyboard_report_t));
+}
+
+bool tud_hid_keyboard_send_keycode(uint8_t modifier, uint8_t keycode[6])
+{
+  hid_keyboard_report_t report = { .modifier = modifier };
+  memcpy(report.keycode, keycode, 6);
+
+  return tud_hid_keyboard_send_report(&report);
 }
+
+#if CFG_TUD_HID_ASCII_TO_KEYCODE_LOOKUP
+
+bool tud_hid_keyboard_send_char(char ch)
+{
+  hid_keyboard_report_t report;
+  varclr_(&report);
+
+  report.modifier   = ( HID_ASCII_TO_KEYCODE[(uint8_t)ch].shift ) ? KEYBOARD_MODIFIER_LEFTSHIFT : 0;
+  report.keycode[0] = HID_ASCII_TO_KEYCODE[(uint8_t)ch].keycode;
+
+  return tud_hid_keyboard_send_report(&report);
+}
+
+bool tud_hid_keyboard_send_string(const char* str, uint32_t interval_ms)
+{
+  // Send each key in string
+  char ch;
+  while( (ch = *str++) != 0 )
+  {
+    char lookahead = *str;
+
+    tud_hid_keyboard_send_char(ch);
+
+    // Blocking delay
+    timeout_blocking_wait(interval_ms);
+
+    /* Only need to empty report if the next character is NULL or the same with
+     * the current one, else no need to send */
+    if ( lookahead == ch || lookahead == 0 )
+    {
+      tud_hid_keyboard_send_report(NULL);
+      timeout_blocking_wait(interval_ms);
+    }
+  }
+
+}
+
+#endif // CFG_TUD_HID_ASCII_TO_KEYCODE_LOOKUP
+
 #endif
 
 //--------------------------------------------------------------------+
@@ -112,15 +168,14 @@ bool tud_hid_mouse_is_busy(void)
   return dcd_edpt_busy(TUD_OPT_RHPORT, _mse_itf.ep_in);
 }
 
-tusb_error_t tud_hid_mouse_send(hid_mouse_report_t const *p_report)
+bool tud_hid_mouse_send(hid_mouse_report_t const *p_report)
 {
-  VERIFY(tud_mounted(), TUSB_ERROR_USBD_DEVICE_NOT_CONFIGURED);
-
-  hidd_interface_t * p_mouse = &_mse_itf;
+  VERIFY( tud_mounted() && !tud_hid_mouse_is_busy() );
 
-  TU_ASSERT( dcd_edpt_xfer(TUD_OPT_RHPORT, p_mouse->ep_in, (void*) p_report, sizeof(hid_mouse_report_t)), TUSB_ERROR_DCD_EDPT_XFER ) ;
+  hidd_interface_t * p_hid = &_mse_itf;
+  memcpy(p_hid->report_buf, p_report, sizeof(hid_mouse_report_t));
 
-  return TUSB_ERROR_NONE;
+  return dcd_edpt_xfer(TUD_OPT_RHPORT, p_hid->ep_in, p_hid->report_buf, sizeof(hid_mouse_report_t));
 }
 #endif
 
@@ -327,4 +382,143 @@ tusb_error_t hidd_xfer_cb(uint8_t rhport, uint8_t edpt_addr, tusb_event_t event,
   return TUSB_ERROR_NONE;
 }
 
+
+/*------------------------------------------------------------------*/
+/* Ascii to Keycode
+ *------------------------------------------------------------------*/
+const hid_ascii_to_keycode_entry_t HID_ASCII_TO_KEYCODE[128] =
+{
+    {0, 0                     }, // 0x00 Null
+    {0, 0                     }, // 0x01
+    {0, 0                     }, // 0x02
+    {0, 0                     }, // 0x03
+    {0, 0                     }, // 0x04
+    {0, 0                     }, // 0x05
+    {0, 0                     }, // 0x06
+    {0, 0                     }, // 0x07
+    {0, HID_KEY_BACKSPACE     }, // 0x08 Backspace
+    {0, HID_KEY_TAB           }, // 0x09 Horizontal Tab
+    {0, HID_KEY_RETURN        }, // 0x0A Line Feed
+    {0, 0                     }, // 0x0B
+    {0, 0                     }, // 0x0C
+    {0, HID_KEY_RETURN        }, // 0x0D Carriage return
+    {0, 0                     }, // 0x0E
+    {0, 0                     }, // 0x0F
+    {0, 0                     }, // 0x10
+    {0, 0                     }, // 0x11
+    {0, 0                     }, // 0x12
+    {0, 0                     }, // 0x13
+    {0, 0                     }, // 0x14
+    {0, 0                     }, // 0x15
+    {0, 0                     }, // 0x16
+    {0, 0                     }, // 0x17
+    {0, 0                     }, // 0x18
+    {0, 0                     }, // 0x19
+    {0, 0                     }, // 0x1A
+    {0, HID_KEY_ESCAPE        }, // 0x1B Escape
+    {0, 0                     }, // 0x1C
+    {0, 0                     }, // 0x1D
+    {0, 0                     }, // 0x1E
+    {0, 0                     }, // 0x1F
+
+    {0, HID_KEY_SPACE         }, // 0x20
+    {1, HID_KEY_1             }, // 0x21 !
+    {1, HID_KEY_APOSTROPHE    }, // 0x22 "
+    {1, HID_KEY_3             }, // 0x23 #
+    {1, HID_KEY_4             }, // 0x24 $
+    {1, HID_KEY_5             }, // 0x25 %
+    {1, HID_KEY_7             }, // 0x26 &
+    {0, HID_KEY_APOSTROPHE    }, // 0x27 '
+    {1, HID_KEY_9             }, // 0x28 (
+    {1, HID_KEY_0             }, // 0x29 )
+    {1, HID_KEY_8             }, // 0x2A *
+    {1, HID_KEY_EQUAL         }, // 0x2B +
+    {0, HID_KEY_COMMA         }, // 0x2C ,
+    {0, HID_KEY_MINUS         }, // 0x2D -
+    {0, HID_KEY_PERIOD        }, // 0x2E .
+    {0, HID_KEY_SLASH         }, // 0x2F /
+    {0, HID_KEY_0             }, // 0x30 0
+    {0, HID_KEY_1             }, // 0x31 1
+    {0, HID_KEY_2             }, // 0x32 2
+    {0, HID_KEY_3             }, // 0x33 3
+    {0, HID_KEY_4             }, // 0x34 4
+    {0, HID_KEY_5             }, // 0x35 5
+    {0, HID_KEY_6             }, // 0x36 6
+    {0, HID_KEY_7             }, // 0x37 7
+    {0, HID_KEY_8             }, // 0x38 8
+    {0, HID_KEY_9             }, // 0x39 9
+    {1, HID_KEY_SEMICOLON     }, // 0x3A :
+    {0, HID_KEY_SEMICOLON     }, // 0x3B ;
+    {1, HID_KEY_COMMA         }, // 0x3C <
+    {0, HID_KEY_EQUAL         }, // 0x3D =
+    {1, HID_KEY_PERIOD        }, // 0x3E >
+    {1, HID_KEY_SLASH         }, // 0x3F ?
+
+    {1, HID_KEY_2             }, // 0x40 @
+    {1, HID_KEY_A             }, // 0x41 A
+    {1, HID_KEY_B             }, // 0x42 B
+    {1, HID_KEY_C             }, // 0x43 C
+    {1, HID_KEY_D             }, // 0x44 D
+    {1, HID_KEY_E             }, // 0x45 E
+    {1, HID_KEY_F             }, // 0x46 F
+    {1, HID_KEY_G             }, // 0x47 G
+    {1, HID_KEY_H             }, // 0x48 H
+    {1, HID_KEY_I             }, // 0x49 I
+    {1, HID_KEY_J             }, // 0x4A J
+    {1, HID_KEY_K             }, // 0x4B K
+    {1, HID_KEY_L             }, // 0x4C L
+    {1, HID_KEY_M             }, // 0x4D M
+    {1, HID_KEY_N             }, // 0x4E N
+    {1, HID_KEY_O             }, // 0x4F O
+    {1, HID_KEY_P             }, // 0x50 P
+    {1, HID_KEY_Q             }, // 0x51 Q
+    {1, HID_KEY_R             }, // 0x52 R
+    {1, HID_KEY_S             }, // 0x53 S
+    {1, HID_KEY_T             }, // 0x55 T
+    {1, HID_KEY_U             }, // 0x55 U
+    {1, HID_KEY_V             }, // 0x56 V
+    {1, HID_KEY_W             }, // 0x57 W
+    {1, HID_KEY_X             }, // 0x58 X
+    {1, HID_KEY_Y             }, // 0x59 Y
+    {1, HID_KEY_Z             }, // 0x5A Z
+    {0, HID_KEY_BRACKET_LEFT  }, // 0x5B [
+    {0, HID_KEY_BACKSLASH     }, // 0x5C '\'
+    {0, HID_KEY_BRACKET_RIGHT }, // 0x5D ]
+    {1, HID_KEY_6             }, // 0x5E ^
+    {1, HID_KEY_MINUS         }, // 0x5F _
+
+    {0, HID_KEY_GRAVE         }, // 0x60 `
+    {0, HID_KEY_A             }, // 0x61 a
+    {0, HID_KEY_B             }, // 0x62 b
+    {0, HID_KEY_C             }, // 0x63 c
+    {0, HID_KEY_D             }, // 0x66 d
+    {0, HID_KEY_E             }, // 0x65 e
+    {0, HID_KEY_F             }, // 0x66 f
+    {0, HID_KEY_G             }, // 0x67 g
+    {0, HID_KEY_H             }, // 0x68 h
+    {0, HID_KEY_I             }, // 0x69 i
+    {0, HID_KEY_J             }, // 0x6A j
+    {0, HID_KEY_K             }, // 0x6B k
+    {0, HID_KEY_L             }, // 0x6C l
+    {0, HID_KEY_M             }, // 0x6D m
+    {0, HID_KEY_N             }, // 0x6E n
+    {0, HID_KEY_O             }, // 0x6F o
+    {0, HID_KEY_P             }, // 0x70 p
+    {0, HID_KEY_Q             }, // 0x71 q
+    {0, HID_KEY_R             }, // 0x72 r
+    {0, HID_KEY_S             }, // 0x73 s
+    {0, HID_KEY_T             }, // 0x75 t
+    {0, HID_KEY_U             }, // 0x75 u
+    {0, HID_KEY_V             }, // 0x76 v
+    {0, HID_KEY_W             }, // 0x77 w
+    {0, HID_KEY_X             }, // 0x78 x
+    {0, HID_KEY_Y             }, // 0x79 y
+    {0, HID_KEY_Z             }, // 0x7A z
+    {1, HID_KEY_BRACKET_LEFT  }, // 0x7B {
+    {1, HID_KEY_BACKSLASH     }, // 0x7C |
+    {1, HID_KEY_BRACKET_RIGHT }, // 0x7D }
+    {1, HID_KEY_GRAVE         }, // 0x7E ~
+    {0, HID_KEY_DELETE        }  // 0x7F Delete
+};
+
 #endif

+ 22 - 26
src/class/hid/hid_device.h

@@ -63,22 +63,26 @@
  */
 bool tud_hid_keyboard_busy(void);
 
-/** \brief        Submit USB transfer
- * \param[in]		  rhport USB Controller ID
- * \param[in,out] p_report address that is used to store data from device. Must be accessible by usb controller (see \ref CFG_TUSB_ATTR_USBRAM)
- * \returns       \ref tusb_error_t type to indicate success or error condition.
- * \retval        TUSB_ERROR_NONE on success
- * \retval        TUSB_ERROR_INTERFACE_IS_BUSY if the interface is already transferring data with device
- * \retval        TUSB_ERROR_DEVICE_NOT_READY if device is not yet configured (by SET CONFIGURED request)
- * \retval        TUSB_ERROR_INVALID_PARA if input parameters are not correct
- * \note          This function is non-blocking and returns immediately. Data will be transferred when USB Host work with this interface.
- *                The result of usb transfer will be reported by the interface's callback function
+/** \brief        Send a keyboard report
+ * \param[in,out] p_report Report data, if NULL, an empty report (all zeroes) is used
+ * \returns        true on success, false otherwise (not mounted or busy)
  */
-tusb_error_t tud_hid_keyboard_send(hid_keyboard_report_t const *p_report);
+bool tud_hid_keyboard_send_report(hid_keyboard_report_t const *p_report);
 
-//--------------------------------------------------------------------+
-// APPLICATION CALLBACK API
-//--------------------------------------------------------------------+
+bool tud_hid_keyboard_send_keycode(uint8_t modifier, uint8_t keycode[6]);
+
+#if CFG_TUD_HID_ASCII_TO_KEYCODE_LOOKUP
+bool tud_hid_keyboard_send_char(char ch);
+bool tud_hid_keyboard_send_string(const char* str, uint32_t interval_ms);
+
+typedef struct{
+  uint8_t shift;
+  uint8_t keycode;
+}hid_ascii_to_keycode_entry_t;
+extern const hid_ascii_to_keycode_entry_t HID_ASCII_TO_KEYCODE[128];
+#endif
+
+/*------------- Callbacks -------------*/
 
 /** \brief      Callback function that is invoked when USB host request \ref HID_REQUEST_CONTROL_GET_REPORT
  *              via control endpoint.
@@ -120,23 +124,15 @@ ATTR_WEAK void tud_hid_keyboard_set_report_cb(hid_report_type_t report_type, uin
  * \retval      false if the interface is not busy meaning the stack successfully transferred data from/to host
  * \note        This function is primarily used for polling/waiting result after \ref tusbd_hid_mouse_send.
  */
-bool tud_hid_mouse_is_busy(void);
+bool tud_hid_mouse_busy(void);
 
 /** \brief        Perform transfer queuing
  * \param[in,out] p_report address that is used to store data from device. Must be accessible by usb controller (see \ref CFG_TUSB_ATTR_USBRAM)
- * \returns       \ref tusb_error_t type to indicate success or error condition.
- * \retval        TUSB_ERROR_NONE on success
- * \retval        TUSB_ERROR_INTERFACE_IS_BUSY if the interface is already transferring data with device
- * \retval        TUSB_ERROR_DEVICE_NOT_READY if device is not yet configured (by SET CONFIGURED request)
- * \retval        TUSB_ERROR_INVALID_PARA if input parameters are not correct
- * \note          This function is non-blocking and returns immediately. Data will be transferred when USB Host work with this interface.
- *                The result of usb transfer will be reported by the interface's callback function
+ * \returns        true on success, false otherwise (not mounted or busy)
  */
-tusb_error_t tud_hid_mouse_send(hid_mouse_report_t const *p_report);
+bool tud_hid_mouse_send(hid_mouse_report_t const *p_report);
 
-//--------------------------------------------------------------------+
-// APPLICATION CALLBACK API
-//--------------------------------------------------------------------+
+/*------------- Callbacks -------------*/
 
 /** \brief      Callback function that is invoked when USB host request \ref HID_REQUEST_CONTROL_GET_REPORT
  *              via control endpoint.

+ 9 - 0
src/common/timeout_timer.h

@@ -67,6 +67,15 @@ static inline bool timeout_expired(timeout_timer_t* tt)
   return ( tusb_hal_millis() - tt->start ) >= tt->interval;
 }
 
+static inline void timeout_blocking_wait(uint32_t msec)
+{
+  timeout_timer_t tt;
+  timeout_set(&tt, msec);
+
+  // blocking delay
+  while ( !timeout_expired(&tt) ) { }
+}
+
 #ifdef __cplusplus
  }
 #endif