aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/_summary.md1
-rw-r--r--docs/feature_rawhid.md65
2 files changed, 66 insertions, 0 deletions
diff --git a/docs/_summary.md b/docs/_summary.md
index 842422665..75b9a83e6 100644
--- a/docs/_summary.md
+++ b/docs/_summary.md
@@ -75,6 +75,7 @@
75 * [Layers](feature_layers.md) 75 * [Layers](feature_layers.md)
76 * [One Shot Keys](one_shot_keys.md) 76 * [One Shot Keys](one_shot_keys.md)
77 * [Pointing Device](feature_pointing_device.md) 77 * [Pointing Device](feature_pointing_device.md)
78 * [Raw HID](feature_rawhid.md)
78 * [Swap Hands](feature_swap_hands.md) 79 * [Swap Hands](feature_swap_hands.md)
79 * [Tap Dance](feature_tap_dance.md) 80 * [Tap Dance](feature_tap_dance.md)
80 * [Tap-Hold Configuration](tap_hold.md) 81 * [Tap-Hold Configuration](tap_hold.md)
diff --git a/docs/feature_rawhid.md b/docs/feature_rawhid.md
new file mode 100644
index 000000000..ed848a4c7
--- /dev/null
+++ b/docs/feature_rawhid.md
@@ -0,0 +1,65 @@
1# Raw HID
2
3Raw HID allows for bidirectional communication between QMK and the host computer over an HID interface. This has many potential use cases, such as switching keymaps on the fly or changing RGB LED colors and modes.
4
5There are two main components to getting raw HID working with your keyboard.
6
7## Keyboard firmware
8
9The implementation is fairly straightforward for the firmware.
10In your `rules.mk` add:
11
12```make
13RAW_ENABLE = yes
14```
15
16In your `keymap.c` include `"raw_hid.h"` and implement the following:
17
18```C
19void raw_hid_receive(uint8_t *data, uint8_t length) {
20 // Your code goes here. data is the packet received from host.
21}
22```
23
24The `"raw_hid.h"` header also declares `void raw_hid_send(uint8_t *data, uint8_t length);` which allows sending packets from keyboard to host. As an example, it can also be used for debugging when building your host application by returning all data back to the host.
25
26```C
27void raw_hid_receive(uint8_t *data, uint8_t length) {
28 raw_hid_send(data, length);
29}
30```
31
32`raw_hid_receive` can receive variable size packets from host with maximum length `RAW_EPSIZE`. `raw_hid_send` on the other hand can send packets to host of exactly `RAW_EPSIZE` length, therefore it should be used with data of length `RAW_EPSIZE`.
33
34Make sure to flash raw enabled firmware before proceeding with working on the host side.
35
36## Host (Windows/macOS/Linux)
37
38This is the more complicated part as it will require some digging.
39
40To connect your host computer to your keyboard with raw HID you need four pieces of information about your keyboard:
41
421. Vendor ID
432. Product ID
443. Usage Page
454. Usage
46
47The first two can easily be found in your keyboard's `config.h` in the keyboard's main directory under `VENDOR_ID` and `PRODUCT_ID`. **Usage Page** is **`0xFF60`** and **Usage** is **`0x0061`**.
48
49### Building your host
50
51You can build your host using any language that has an available HID implementation library if you don't wish to make your own. The ones we know of for popular languages are:
52
53* Node: [node-hid](https://github.com/node-hid/node-hid).
54* C: [hidapi](https://github.com/libusb/hidapi).
55* Java: [purejavahidapi](https://github.com/nyholku/purejavahidapi) and [hid4java](https://github.com/gary-rowe/hid4java).
56* Python: [pyhidapi](https://pypi.org/project/hid/).
57
58This is not an exhaustive cross-platform list but should get you started. There are no special requirements for using raw HID so any HID library should work.
59
60Now that you have all four pieces of information required to open HID interface to your keyboard. All you need to do is use your library's available functions to open the device with its ID parameters.
61
62Note that Vendor ID and Product ID are not actually required to open the device. They are used only to filter to a specific device out of the many HID devices you have plugged in. Many libraries will give you the option to open the device using Product Name or Manufacturer Name instead, `node-hid` being a prime example. This will create issues for devices with builtin USB Hub or any extra HID interfaces where you will have multiple interfaces with the same name or from the same manufacturer. The Vendor ID together with Product ID create a unique designation to a single interface and will not exhibit this problem. Therefore, even if your library doesn't require you to, it is best to use them to avoid issues.
63Unlike Vendor ID and Product ID though, Usage Page and Usage are necessary for successful communication.
64
65It should go without saying that regardless of the library you're using, you should always make sure to close the interface when finished. Depending on the operating system and your particular environment there may be issues connecting to it again afterwards with another client or another instance of the same client if it's not explicitly closed.