Elevate your projects with these smooth integrations of the Human Interface Device (HID) class and unlock the potential of the AVR DU microcontroller. This guide introduces two creative keyboard examples, showcasing how basic user inputs can be transformed into USB-compatible outputs you can use with your computer!
- MPLAB® X IDE 6.20 or newer
- MPLAB® XC8 Compiler 2.46 or newer
- MPLAB® Code Configurator (MCC) 5.5.1 or newer
- USB 2.0 Specification
- USB Device Stack User Guide
- USB Human Interface Device (HID) Specification
- Device Class Definition for HID 1.11
This repository contains the code for two keyboard examples, both utilizing the HID USB class on the AVR DU microcontroller (MCU). The AVR DU is integrated into the AVR64DU32 Curiosity Nano Board. The repository structure is as follows:
- Main Folder
- README.md: A general article on HID concepts and usage
- avr64du32-cnano-hid-binary-keyboard-mplab-mcc.X/
- README.md: Description and complete project files for the Binary Keyboard example
- avr64du32-cnano-hid-joystick-keyboard-mplab-mcc.X/
- README.md: Description and complete project files for the Joystick Keyboard example
These projects demonstrate the versatility of the HID class, seamlessly converting user actions into recognizable Universal Serial Bus (USB) communication. The following sections explore what the HID class is and how it works in USB devices.
USB devices are segmented into device classes that have similar data transport requirements and share a singel class driver. The USB HID class supports devices that allow users to control computer system operations. Some common examples of HID class devices are keyboards, computer mice, joysticks and switches.
The HID class defines two protocols: Boot and Report. HID devices use the subclass descriptor to indicate whether they support Boot mode. The Boot protocol provides a simplified communication method, optimized for basic inputs, and enables quick recognition by the basic input/output system (BIOS). This protocol is specifically designed for devices like keyboards and mice. Both the joystick and the binary keyboard utilize the Boot protocol. More specifically, they select the keyboard protocol, which is a type of Boot protocol.
Boot protocol: Lightweight and typically used by mice and keyboards.
The Report protocol is more complex, because it uses a detailed report descriptor to define how data is exchanged. Parsing the report descriptor requires a large amount of code, making the protocol more resource demanding. It is suitable for devices that require more advanced functionality beyond basic input, as it allows for an extensive customization of device behavior and data reporting. Examples of devices using the Report protocol include gaming consoles and touchscreens.
Report protocol: Complex and typically used by gaming consoles and touchscreens.
When a HID device connects to a computer, the host requests a HID descriptor. The descriptor tells the host how to interpret the reports from the device. For a Keyboard Boot Protocol, the host will expect to receive key codes representing characters that are defined on the Keyboard Usage Page.
Usage ID | Usage Name |
---|---|
00 | Reserved |
01 | Keyboard ErrorRollOver |
02 | Keyboard POSTFail |
03 | Keyboard ErrorUndefined |
04 | Keyboard a and A |
05 | Keyboard b and B |
06 | Keyboard c and C |
07 | Keyboard d and D |
08 | Keyboard e and E |
09 | Keyboard f and F |
After the setup, the HID device will start sending 8-byte input reports to indicate which keys are currently pressed.
The input report contains a modifier byte for <Shift>
and <CTRL>
and an array of key codes for letters
and symbols. The key code for a character or a modifier is called a Usage ID, and the IDs are defined on the
Keyboard Page. The host computer translates the Usage IDs according to the Usage Page and displays
them on the screen.
typedef struct
{
uint8_t Modifier; // Keyboard modifier byte
uint8_t Reserved; // Reserved, always set to 0
uint8_t KeyCode[6]; // Key codes of the currently pressed keys
} USB_KEYBOARD_REPORT_DATA_t;
The binary keyboard uses the HID class to interface with eight switches, representing the eight bits of an ASCII character. It is designed to illustrate how text on computers is fundamentally stored as binary numbers. In the example, the binary input values are mapped to HID Usage IDs and sent to the PC over USB.
One of the main differences between HID and ASCII is how they handle characters and modifiers. ASCII codes always represent the same characters. The encoding distinguishes between lowercase and uppercase letters, like 'a' and 'A', and does not include special keys or modifiers, such as Ctrl or Shift. In contrast, HID uses modifier keys to change the case and to access special characters. Rather than specific characters, HID values are tied to key positions on a keyboard. This means that the interpretation of certain characters (like /, < or ^) may vary with different keyboard layouts or languages, while ASCII codes remain consistent across languages.
The joystick keyboard uses the HID class to interface with a joystick that loops through the alphabet, which works smoothly because the HID values increase in alphabetic order.
Pushing the joystick down displays the next letter in the alphabet (HID value +1)
and pushing it up returns the prior letter (HID value -1). To start writing the next letter, move the joystick to the right. To edit a prior letter, move the joystick to the left. To select <Enter>
, press the blue button. This keyboard works like text input on vintage arcade machines, allowing users to, for example, write their names.