From 4366f118ed7492738dc96f717d29296feaaeb184 Mon Sep 17 00:00:00 2001 From: LiPeng Date: Fri, 4 Jul 2025 18:12:21 +0800 Subject: [PATCH] feat(usb): add ALT escape input for USB HID keyboard --- .../usb/host/cherryusb_host/main/hid.c | 52 +++++++++++++++++++ .../usb/host/hid/main/hid_host_example.c | 52 +++++++++++++++++++ 2 files changed, 104 insertions(+) diff --git a/examples/peripherals/usb/host/cherryusb_host/main/hid.c b/examples/peripherals/usb/host/cherryusb_host/main/hid.c index ae50189eda..3178d48eaa 100644 --- a/examples/peripherals/usb/host/cherryusb_host/main/hid.c +++ b/examples/peripherals/usb/host/cherryusb_host/main/hid.c @@ -37,6 +37,13 @@ typedef struct { #define KEYBOARD_ENTER_MAIN_CHAR '\r' /* When set to 1 pressing ENTER will be extending with LineFeed during serial debug output */ #define KEYBOARD_ENTER_LF_EXTEND 1 +/* When set to 1, numbers entered from the numeric keypad while ALT is pressed will be escaped */ +#define KEYBOARD_ENTER_ALT_ESCAPE 1 + +#if KEYBOARD_ENTER_ALT_ESCAPE +static bool escaping = false; +static unsigned char escap_hex = 0; +#endif /** * @brief Scancode to ascii table @@ -140,6 +147,25 @@ static inline bool hid_keyboard_is_modifier_shift(uint8_t modifier) return false; } +#if KEYBOARD_ENTER_ALT_ESCAPE +/** + * @brief HID Keyboard modifier verification for capitalization application (right or left alt) + * + * @param[in] modifier + * @return true Modifier was pressed (left or right alt) + * @return false Modifier was not pressed (left or right alt) + * + */ +static inline bool hid_keyboard_is_modifier_alt(uint8_t modifier) +{ + if (((modifier & HID_MODIFIER_LALT) == HID_MODIFIER_LALT) || + ((modifier & HID_MODIFIER_RALT) == HID_MODIFIER_RALT)) { + return true; + } + return false; +} +#endif + /** * @brief HID Keyboard get char symbol from key code * @@ -156,6 +182,18 @@ static inline bool hid_keyboard_get_char(uint8_t modifier, { uint8_t mod = (hid_keyboard_is_modifier_shift(modifier)) ? 1 : 0; +#if KEYBOARD_ENTER_ALT_ESCAPE + if (escaping) { + if ((key_code >= HID_KBD_USAGE_KPD1) && (key_code <= HID_KBD_USAGE_KPD0)) { + if (key_code == HID_KBD_USAGE_KPD0) { + key_code = HID_KBD_USAGE_KPD1 - 1; + } + escap_hex = escap_hex * 10 + (key_code - (HID_KBD_USAGE_KPD1 - 1)); + } + return false; + } +#endif + if ((key_code >= HID_KBD_USAGE_A) && (key_code <= HID_KBD_USAGE_QUESTION)) { *key_char = keycode2ascii[key_code][mod]; } else { @@ -233,6 +271,20 @@ static void usbh_hid_keyboard_report_callback(void *arg, int nbytes) static uint8_t prev_keys[sizeof(kb_report->key)] = { 0 }; key_event_t key_event; +#if KEYBOARD_ENTER_ALT_ESCAPE + if (hid_keyboard_is_modifier_alt(kb_report->modifier)) { + if (escaping == false) { + escaping = true; + escap_hex = 0; + } + } else { + if (escaping && escap_hex > 0) { + escaping = false; + hid_keyboard_print_char(escap_hex); + } + } +#endif + for (int i = 0; i < sizeof(kb_report->key); i++) { // key has been released verification diff --git a/examples/peripherals/usb/host/hid/main/hid_host_example.c b/examples/peripherals/usb/host/hid/main/hid_host_example.c index 3dfff0b931..be8ee95cc2 100644 --- a/examples/peripherals/usb/host/hid/main/hid_host_example.c +++ b/examples/peripherals/usb/host/hid/main/hid_host_example.c @@ -83,6 +83,13 @@ typedef struct { #define KEYBOARD_ENTER_MAIN_CHAR '\r' /* When set to 1 pressing ENTER will be extending with LineFeed during serial debug output */ #define KEYBOARD_ENTER_LF_EXTEND 1 +/* When set to 1, numbers entered from the numeric keypad while ALT is pressed will be escaped */ +#define KEYBOARD_ENTER_ALT_ESCAPE 1 + +#if KEYBOARD_ENTER_ALT_ESCAPE +static bool escaping = false; +static unsigned char escap_hex = 0; +#endif /** * @brief Scancode to ascii table @@ -187,6 +194,25 @@ static inline bool hid_keyboard_is_modifier_shift(uint8_t modifier) return false; } +#if KEYBOARD_ENTER_ALT_ESCAPE +/** + * @brief HID Keyboard modifier verification for capitalization application (right or left alt) + * + * @param[in] modifier + * @return true Modifier was pressed (left or right alt) + * @return false Modifier was not pressed (left or right alt) + * + */ +static inline bool hid_keyboard_is_modifier_alt(uint8_t modifier) +{ + if (((modifier & HID_LEFT_ALT) == HID_LEFT_ALT) || + ((modifier & HID_RIGHT_ALT) == HID_RIGHT_ALT)) { + return true; + } + return false; +} +#endif + /** * @brief HID Keyboard get char symbol from key code * @@ -203,6 +229,18 @@ static inline bool hid_keyboard_get_char(uint8_t modifier, { uint8_t mod = (hid_keyboard_is_modifier_shift(modifier)) ? 1 : 0; +#if KEYBOARD_ENTER_ALT_ESCAPE + if (escaping) { + if ((key_code >= HID_KEY_KEYPAD_1) && (key_code <= HID_KEY_KEYPAD_0)) { + if (key_code == HID_KEY_KEYPAD_0) { + key_code = HID_KEY_KEYPAD_1 - 1; + } + escap_hex = escap_hex * 10 + (key_code - (HID_KEY_KEYPAD_1 - 1)); + } + return false; + } +#endif + if ((key_code >= HID_KEY_A) && (key_code <= HID_KEY_SLASH)) { *key_char = keycode2ascii[key_code][mod]; } else { @@ -289,6 +327,20 @@ static void hid_host_keyboard_report_callback(const uint8_t *const data, const i static uint8_t prev_keys[HID_KEYBOARD_KEY_MAX] = { 0 }; key_event_t key_event; +#if KEYBOARD_ENTER_ALT_ESCAPE + if (hid_keyboard_is_modifier_alt(kb_report->modifier.val)) { + if (escaping == false) { + escaping = true; + escap_hex = 0; + } + } else { + if (escaping && escap_hex > 0) { + escaping = false; + hid_keyboard_print_char(escap_hex); + } + } +#endif + for (int i = 0; i < HID_KEYBOARD_KEY_MAX; i++) { // key has been released verification