1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
// Copyright 2021-2022 Jacob Alexander
//
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.
use usbd_hid::descriptor::generator_prelude::*;
/// NKRO Keyboard - HID Bitmap
///
/// This is a simplified NKRO descriptor as comparied to kiibohd/controller.
/// It uses 1 extra byte in each packet, but easier to understand and parse.
///
/// NOTES:
/// Supports all keys defined by the spec.
/// 0 represents "no keys pressed" so it is excluded.
/// Supports all keys defined by the spec, except 1-3 which define error events
/// and 0 which is "no keys pressed"
/// See <https://usb.org/sites/default/files/hut1_22.pdf> Chapter 10
///
/// Special bits:
/// 0x00 - Reserved (represents no keys pressed, not useful in a bitmap)
/// 0x01 - ErrorRollOver
/// 0x02 - POSTFail
/// 0x03 - ErrorUndefined
/// 0xA5..0xAF - Reserved
/// 0xDE..0xDF - Reserved
/// 0xE8..0xFFFF - Not specified (Reserved in protocol)
///
/// Compatibility Notes:
/// - Using a second endpoint for a boot mode device helps with compatibility
/// - DO NOT use Padding in the descriptor for bitfields
/// (Mac OSX silently fails... Windows/Linux work correctly)
/// - DO NOT use Report IDs (to split the keyboard report), Windows 8.1 will not update
/// keyboard correctly (modifiers disappear)
/// (all other OSs, including OSX work fine...)
/// (you can use them *iff* you only have 1 per collection)
/// - Mac OSX and Windows 8.1 are extremely picky about padding
#[gen_hid_descriptor(
(collection = APPLICATION, usage_page = GENERIC_DESKTOP, usage = KEYBOARD) = {
// LED Report
(usage_page = LEDS, usage_min = 0x01, usage_max = 0x05) = {
#[packed_bits 8] #[item_settings data,variable,absolute] leds=output;
};
// 1-231 (29 bytes/232 bits)
(usage_page = KEYBOARD, usage_min = 0x01, usage_max = 0xE7) = {
#[packed_bits 232] #[item_settings data,variable,absolute] keybitmap=input;
};
}
)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct KeyboardNkroReport {
pub leds: u8,
pub keybitmap: [u8; 29],
}
/// System Control and Consumer Control
///
/// System Control 0x81 through 0xB7
/// See <https://usb.org/sites/default/files/hut1_22.pdf> Chapter 4 (Generic Desktop Page)
///
/// Consumer Control 0x00 through 0x29D
/// See <https://usb.org/sites/default/files/hut1_22.pdf> Chapter 15 (Consumer Page)
#[gen_hid_descriptor(
(collection = APPLICATION, usage_page = CONSUMER, usage = CONSUMER_CONTROL) = {
// Consumer Control Collection - Media Keys (16 bits)
//
// NOTES:
// Not bothering with NKRO for this table. If there's a need, I can implement it. -HaaTa
// Using a 1KRO scheme
(usage_page = CONSUMER, usage_min = 0x00, usage_max = 0x29D) = {
#[item_settings data,array,absolute,not_null] consumer_ctrl=input;
};
// System Control Collection (8 bits)
//
// NOTES:
// Not bothering with NKRO for this table. If there's a need, I can implement it. -HaaTa
// Using a 1KRO scheme
// XXX (HaaTa):
// Logical Minimum must start from 1 (not 0!) to resolve MS Windows issues
// Usage Minimum must start from 129 (0x81) to fix macOS scrollbar issues
(usage_page = GENERIC_DESKTOP, usage_min = 0x81, usage_max = 0xB7, logical_min = 1) = {
#[item_settings data,array,absolute,not_null] system_ctrl=input;
};
}
)]
pub struct SysCtrlConsumerCtrlReport {
pub consumer_ctrl: u16,
pub system_ctrl: u8,
}
/// Mouse Interface
/// MouseReport describes a report and its companion descriptor that can be used
/// to send mouse movements and button presses to a host.
#[gen_hid_descriptor(
(collection = APPLICATION, usage_page = GENERIC_DESKTOP, usage = MOUSE) = {
(collection = PHYSICAL, usage = POINTER) = {
(usage_page = BUTTON, usage_min = BUTTON_1, usage_max = BUTTON_8) = {
#[packed_bits 8] #[item_settings data,variable,absolute] buttons=input;
};
(usage_page = GENERIC_DESKTOP,) = {
(usage = X,) = {
#[item_settings data,variable,relative] x=input;
};
(usage = Y,) = {
#[item_settings data,variable,relative] y=input;
};
(usage = WHEEL,) = {
#[item_settings data,variable,relative] vert_wheel=input;
};
};
(usage_page = CONSUMER, usage = AC_PAN,) = {
#[item_settings data,variable,relative] horz_wheel=input;
};
};
}
)]
pub struct MouseReport {
pub buttons: u8,
pub x: i16,
pub y: i16,
pub vert_wheel: i8, // Scroll down (negative) or up (positive) this many units
pub horz_wheel: i8, // Scroll left (negative) or right (positive) this many units
}
/// HID-IO Interface
/// NOTE: tx must use push_raw_input (not push_input) as serde doesn't currently support
/// arrays larger than 32 bytes.
///
/// Generic hidraw interface intended to be used with:
/// <https://github.com/hid-io/hid-io-core/tree/master/hid-io-protocol>
#[gen_hid_descriptor(
(collection = APPLICATION, usage_page = 0xFF1C, usage = 0x1100) = {
(usage = 0x01,) = { rx=output; };
(usage = 0x02,) = { tx=input; };
}
)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct HidioReport {
rx: [u8; 64],
tx: [u8; 64],
}