ESPHome 2026.11.0-dev
Loading...
Searching...
No Matches
keyboard.h
Go to the documentation of this file.
1#pragma once
2
3#if defined(USE_ESP32_VARIANT_ESP32P4) || defined(USE_ESP32_VARIANT_ESP32S2) || defined(USE_ESP32_VARIANT_ESP32S3) || \
4 defined(USE_ESP32_VARIANT_ESP32S31) || defined(USE_ESP32_VARIANT_ESP32H4)
5
7
8#include "tusb.h"
9// tusb.h only pulls the HID class in when CFG_TUD_HID is set, which the static analysis build does not do
10#include "class/hid/hid_device.h"
11
13
14static constexpr uint8_t REPORT_ID_KEYBOARD = 1;
15static constexpr uint8_t REPORT_ID_CONSUMER = 2;
16static constexpr uint8_t ENDPOINT_IN = 0x81;
17static constexpr uint8_t POLL_INTERVAL_MS = 10;
18
19// One HID interface carrying a keyboard and a consumer control (media keys), told apart by report id.
20// Report ids rule out the boot protocol, so the interface declares no boot protocol, as TinyUSB's
21// composite example does.
22inline constexpr uint8_t HID_REPORT_DESCRIPTOR[] = {
23 TUD_HID_REPORT_DESC_KEYBOARD(HID_REPORT_ID(REPORT_ID_KEYBOARD)),
24 TUD_HID_REPORT_DESC_CONSUMER(HID_REPORT_ID(REPORT_ID_CONSUMER)),
25};
26
27// esp_tinyusb ships default configuration descriptors for CDC, MSC and NCM only, so the keyboard supplies its own
28inline constexpr uint8_t CONFIGURATION_DESCRIPTOR[] = {
29 TUD_CONFIG_DESCRIPTOR(1, 1, 0, TUD_CONFIG_DESC_LEN + TUD_HID_DESC_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100),
30 TUD_HID_DESCRIPTOR(0, 0, HID_ITF_PROTOCOL_NONE, sizeof(HID_REPORT_DESCRIPTOR), ENDPOINT_IN, CFG_TUD_HID_EP_BUFSIZE,
31 POLL_INTERVAL_MS),
32};
33
34class TinyUSBKeyboard final : public Component {
35 public:
36 void setup() override { this->disable_loop(); }
37 void loop() override;
38 void dump_config() override;
39
41 void press_key(uint8_t keycode, uint8_t modifiers) { this->set_keyboard_(keycode, modifiers); }
42 void release_keys() { this->set_keyboard_(0, 0); }
44 void press_media(uint16_t usage) { this->set_consumer_(usage); }
45 void release_media() { this->set_consumer_(0); }
46
47 protected:
48 void set_keyboard_(uint8_t keycode, uint8_t modifiers);
49 void set_consumer_(uint16_t usage);
51 void flush_();
52
53 // The wanted state of each report, resent until the endpoint accepts it so a release is never lost.
54 // Only the latest state is kept, so consecutive key actions need a short delay between them.
55 uint16_t usage_{0};
56 uint8_t keycode_{0};
57 uint8_t modifiers_{0};
58 bool keyboard_pending_{false};
59 bool consumer_pending_{false};
60 bool wakeup_requested_{false};
61};
62
63} // namespace esphome::tinyusb_keyboard
64
65#endif // USE_ESP32_VARIANT_ESP32P4 || USE_ESP32_VARIANT_ESP32S2 || USE_ESP32_VARIANT_ESP32S3 ||
66 // USE_ESP32_VARIANT_ESP32S31 || USE_ESP32_VARIANT_ESP32H4
void disable_loop()
Disable this component's loop.
void press_media(uint16_t usage)
Press one consumer control usage, for example 0xE9 for volume up.
Definition keyboard.h:44
void flush_()
Sends whatever changed; a report the endpoint cannot take yet is retried from loop()
Definition keyboard.cpp:26
void set_keyboard_(uint8_t keycode, uint8_t modifiers)
Definition keyboard.cpp:13
void press_key(uint8_t keycode, uint8_t modifiers)
Press one key (HID usage id) with the given modifier bitmask; every other key is reported released.
Definition keyboard.h:41
constexpr uint8_t CONFIGURATION_DESCRIPTOR[]
Definition keyboard.h:28
constexpr uint8_t HID_REPORT_DESCRIPTOR[]
Definition keyboard.h:22